有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java为什么双击安卓客户端接收数据?

当我第一次点击登录按钮时,数据发送到服务器,服务器收到第一次点击时返回的数据数据不显示在安卓客户端屏幕上。当我再次按下登录按钮时,它再次发送数据,然后在客户端屏幕上显示数据。。。请帮帮我。为什么在第二次点击时收到数据我希望在第一次点击时收到我的数据? 以下是代码:

客户端tcpip代码

    public class SockProg {

    private Socket socket;
    DataOutputStream dataOutputStream;
    DataInputStream dataInputStream;
    String data;
    String serverip = "192.168.1.7";
    int serverport = 4444;



    public void connetToServer(){
        try {
            socket = new Socket(serverip, serverport);
            Log.i("AsyncTank", "doInBackgoung: Created Socket");
        } catch (UnknownHostException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        if (socket.isConnected()) {
            try {
                dataOutputStream = new DataOutputStream(
                        socket.getOutputStream());
                dataInputStream = new DataInputStream(socket.getInputStream());


            } catch (IOException e) {
                e.printStackTrace();
            }

        }
    }
    public void writeToStream(String message) {
         try {
             if (socket.isConnected()){
                 dataOutputStream.writeUTF(message.toString());
            } else {
                Log.i("AsynkTask", "writeToStream : Cannot write to stream, Socket is closed");
            }
            } catch (Exception e) {
            Log.i("AsynkTask", "writeToStream : Writing failed");
           }  
    }
    public String readFromStream() {
         String ret = null;
        try {
            if (socket.isConnected()) {
                Log.i("AsynkTask", "readFromStream : Reading message");
                 ret=dataInputStream.readUTF();
                Log.i("AsynkTask", "readFromStream : read "+ret);

            } else {
                Log.i("AsynkTask", "readFromStream : Cannot Read, Socket is closed");
            }
        } catch (Exception e) {
            Log.i("AsynkTask", "readFromStream : Reading failed"+e.getClass());
        }
        return ret;
        }
    public void CloseSockets(){
        if (socket != null) {
            try {
                socket.close();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }

        if (dataOutputStream != null) {
            try {
                dataOutputStream.close();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }

        if (dataInputStream != null) {
            try {
                dataInputStream.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

以下是同步线程的代码

    public class TCP implements Runnable {


    String data;
    SockProg sp;
    Thread thh;
    private static String rdata;

    public TCP(SockProg spr, String val) {
        sp = spr;
        data = val;
        thh = new Thread(this);
        thh.start();
    }


    @Override
    public void run() {
        synchronized(sp) { // synchronized block
            //rdata= sp.DataSendRecive(data);
            sp.connetToServer();
            sp.writeToStream(data);
            rdata=sp.readFromStream();
            sp.CloseSockets();
          }
    }
    public static String getData(){
        return rdata;
    }


}

以下是登录活动的代码

 @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_login);
        msg = (TextView) findViewById(R.id.msg_log);
        login = (Button) findViewById(R.id.btn_login);

        login.setOnClickListener(new View.OnClickListener() {

            @Override
            public void onClick(View v) {
                // try{

                txtph = (EditText) findViewById(R.id.txt_phnum);
                txtpass = (EditText) findViewById(R.id.txt_pass);
                ph = txtph.getText().toString();
                pass = txtpass.getText().toString();

                int ch = 0;

                if (ph.equals("") || ph == null) {
                    msg.setText("Please Enter Mobile Number....\n");
                    ch++;
                }
                if (pass.equals("") || pass == null) {
                    if (ch == 0) {
                        msg.setText("Please Enter your Password....\n");
                    } else {
                        msg.append("Please Enter your Password....\n");
                    }

                    ch++;
                }
                if (ch == 0) {

                    ArrayList<String> ph_pass = new ArrayList<String>();
                    ph_pass.add(0, "LoginAccount");
                    ph_pass.add(1, ph);
                    ph_pass.add(2, pass);
                    SockProg sp=new SockProg();
                    TCP t=new TCP(sp, ph_pass.toString());
                    data=t.getData();
                    msg.setText(data);


                }
            }

        });

    }

共 (1) 个答案

  1. # 1 楼答案

    这看起来像是异步编码延迟的典型案例。TCP类是可运行的,因此当它第一次被调用(第一次单击登录按钮)时,它开始运行,但线程没有足够的时间来完成

    rdata=sp.readFromStream();
    

    在run()方法中,因此data=t.getData();不会返回任何有用的内容。第二次单击为runnable提供了足够的时间,用一些数据填充rdata,从而使程序正常运行

    在处理异步代码时,需要一种更好的方法来等待代码完成它正在做的事情

    为什么rdata是静态类型?将其设置为非静态,然后更改getData()方法,如下所示:

    public synchronized String getData()