我有一个AsyncTask
用于创建Socket
连接。在我的doInBackground()
方法中,我有:
Socket socket = new Socket(HOST_NAME, PORT_NUMBER);
就我而言,当我尝试通过蜂窝网络连接时,这行代码会挂起。它永远不会完成执行,最终应用程序崩溃。因为来自Server
的信息对我来说是必要的,所以我做了类似的事情:
AttemptConnection attemptConnection = new AttemptConnection(); // this is the AsyncTask
attemptConnection.execute().get();
现在我意识到这很糟糕,因为AsyncTask
的目的是与主线程并行运行,这就是停止对主线程的处理。但是,在获取服务器的信息之前,我的应用程序无法真正去任何地方,因此我需要完成此AsyncTask。
因为Socket
连接失败并且挂起了一段时间,但是有些情况会导致我的设备冻结以及我的应用程序最终崩溃。所以我想要更好的东西。我想出的解决方案是:
attemptConnection.execute();
try {
Thread.sleep(3000);
} catch (Exception e) {
}
attemptConnection.cancel();
但我想知道这是否更好?我无法在内部取消该流程,因为永远无法访问应该捕获try / catch
连接错误的Socket
。代码挂起,没有错误被捕获。但上述想法似乎也是一种真正的hacky方式;我想知道这种方法是否和我的直觉告诉我的那样糟糕,如果是这样,有什么更好的方法可以解决这个问题?
答案 0 :(得分:2)
通常,您必须对ASyncTask进行编码,以便无法无限期挂起。
在特定情况下,您可以通过在创建套接字时指定超时(可能是几秒钟)来实现此目的。如果无法在合理的时间内建立Socket连接,则会强制抛出异常。有关如何执行此操作的指导,请参阅Setting a timeout for socket operations。
当然,无论连接是成功还是失败,都不应该阻止主线程等待结果。您应该通过常规方式从ASyncTask发送结果,方法是返回doInBackground()
的结果。