当我第一次点击登录按钮时,数据发送到服务器和服务器接收的数据作为回报,首次点击数据不显示在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);
}
}
});
}
答案 0 :(得分:0)
这看起来像是异步编码延迟的经典案例。 TCP类是一个可运行的,因此当它第一次被调用时(第一次点击登录按钮)它开始运行,但是线程没有足够的时间来完成
rdata=sp.readFromStream();
在run()方法中,因此data=t.getData();
没有返回任何有用的东西。第二次单击,为runnable提供了足够的时间用rdata填充一些数据,因此你的程序可以工作。
使用异步代码时,您需要一种更好的方法来等待代码完成它正在做的事情。
为什么rdata是静态类型?将其设置为非静态,然后更改getData()方法,如下所示:
public synchronized String getData()