我正在尝试在Android上创建客户端-服务器应用程序。我想要一个初始化套接字并将其返回到主类的类。我没有创建和连接套接字的任何问题(我的服务器正在正确处理连接),但是当我尝试将创建的套接字返回给主类时,它为null。我想念什么?
我尝试使用AsyncTask。
这是主类的代码:
public class MainActivity extends AppCompatActivity {
private Socket socket;
private SocketHandler sH;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
sH = new SocketHandler();
sH.start();
socket = sH.getSocket();
if(socket == null){
System.out.println("null");
}else{
System.out.println("not null");
}
}
}
这是初始化套接字的类的代码:
public class SocketHandler extends Thread {
private Socket socket;
public Socket getSocket(){
return socket;
}
@Override
public void run(){
try{
socket = new Socket("192.168.0.4", 9999);
}catch (IOException e){
e.printStackTrace();
}
}
}
答案 0 :(得分:3)
线程是并行运行的,这意味着不能保证套接字连接会立即完成,但是您错误地认为这会导致经典竞态条件,因为此时调用getSocket()
时连接仍然正在建立(但此过程尚未完成),因此socket
变量仍然是null
,因为它是在创建SocketHandler
实例时初始化的。
您需要同步代码,执行回调或(出于测试目的)在调用getSocket()
之前稍等片刻或读取几次(即循环+一定的延迟/超时,除非套接字值是不是null
(但请注意,如果套接字连接失败,您应该期望null
也是有效值)。
此外,如果在单独的线程中创建套接字,为什么还要在主线程中读取套接字?您是否应该在该线程中完成所有套接字的工作?