为什么双击android客户端收到数据?

时间:2013-12-20 10:22:45

标签: java android sockets

当我第一次点击登录按钮时,数据发送到服务器和服务器接收的数据作为回报,首次点击数据不显示在Android客户端屏幕上。当我再次按下登录按钮时,它再次发送数据然后在客户端屏幕上显示数据...请帮助我。为什么在secind上收到数据点击我想在第一次点击时收到我的数据? 这是代码:

客户 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();
            }
        }
    }
}

这是 sychronized thread

的代码
    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 个答案:

答案 0 :(得分:0)

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

rdata=sp.readFromStream();
在run()方法中,

因此data=t.getData();没有返回任何有用的东西。第二次单击,为runnable提供了足够的时间用rdata填充一些数据,因此你的程序可以工作。

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

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

public synchronized String getData()