Java Android 4.x中SocketTimeoutException崩溃异步任务
我在SocketChannel.connect超时的情况下遇到了问题。下面的代码在我的旧安卓2.3手机和旧安卓3.2平板电脑中运行良好,但在安卓4.2.2中崩溃:Java Android 4.x中SocketTimeoutException崩溃异步任务,java,android,android-asynctask,Java,Android,Android Asynctask,我在SocketChannel.connect超时的情况下遇到了问题。下面的代码在我的旧安卓2.3手机和旧安卓3.2平板电脑中运行良好,但在安卓4.2.2中崩溃: @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main);
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
tvResult = (TextView) findViewById(R.id.tvResult);
btnTest = (Button) this.findViewById(R.id.btnTest);
btnTest.setOnClickListener(doTest);
}
protected View.OnClickListener doTest = new View.OnClickListener() {
@Override
public void onClick(View v) {
new AsyncTest().execute();
}
};
private class AsyncTest extends AsyncTask {
private String result = "";
@Override
protected Void doInBackground(Void... params) {
InetSocketAddress addr = new InetSocketAddress("192.168.0.13", 4040);
boolean bConnect = false;
try {
SocketChannel clntChan = SocketChannel.open();
bConnect = clntChan.connect(addr);
if (bConnect) {
clntChan.close();
result = "Connected";
} else {
result = "Did not connected";
}
} catch (Exception e) {
Log.e(TAG, "Exception " + e.getMessage());
result = "Exception " + e.getMessage();
}
return null;
}
@Override
protected void onPostExecute(Void ret) {
tvResult.setText (result);
}
}
我正在测试没有人监听端口4040 192.168.0.13的情况。在Android2.3中,try/catch将捕获一个“连接超时”异常(如预期的那样)。在Android 4.x中,我得到了以下信息:
FATAL EXCEPTION: AsyncTask #1
java.lang.RuntimeException: An error occured while executing doInBackground()
at android.os.AsyncTask$3.done(AsyncTask.java:299)
at java.util.concurrent.FutureTask.finishCompletion(FutureTask.java:352)
at java.util.concurrent.FutureTask.setException(FutureTask.java:219)
at java.util.concurrent.FutureTask.run(FutureTask.java:239)
at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:230)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1080)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:573)
at java.lang.Thread.run(Thread.java:838)
Caused by: java.lang.AssertionError: java.net.SocketTimeoutException: failed to connect to /192.168.0.13 (port 4040) after 90000ms
at libcore.io.IoBridge.connect(IoBridge.java:102)
at java.nio.SocketChannelImpl.connect(SocketChannelImpl.java:177)
at br.com.dqsoft.testeconnect.MainActivity$AsyncTest.doInBackground(MainActivity.java:63)
at br.com.dqsoft.testeconnect.MainActivity$AsyncTest.doInBackground(MainActivity.java:1)
at android.os.AsyncTask$2.call(AsyncTask.java:287)
at java.util.concurrent.FutureTask.run(FutureTask.java:234)
... 4 more
Caused by: java.net.SocketTimeoutException: failed to connect to /192.168.0.13 (port 4040) after 90000ms
at libcore.io.IoBridge.connectErrno(IoBridge.java:176)
at libcore.io.IoBridge.connect(IoBridge.java:112)
at libcore.io.IoBridge.connect(IoBridge.java:100)
... 9 more
致命异常:AsyncTask#1
java.lang.RuntimeException:执行doInBackground()时出错
在android.os.AsyncTask$3.done(AsyncTask.java:299)
位于java.util.concurrent.FutureTask.finishCompletion(FutureTask.java:352)
位于java.util.concurrent.FutureTask.setException(FutureTask.java:219)
位于java.util.concurrent.FutureTask.run(FutureTask.java:239)
在android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:230)
位于java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1080)
位于java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:573)
运行(Thread.java:838)
原因:java.lang.AssertionError:java.net.SocketTimeoutException:90000毫秒后连接到/192.168.0.13(端口4040)失败
位于libcore.io.IoBridge.connect(IoBridge.java:102)
位于java.nio.SocketChannelImpl.connect(SocketChannelImpl.java:177)
在br.com.dqsoft.testeconnect.MainActivity$AsyncTest.doInBackground(MainActivity.java:63)
在br.com.dqsoft.testeconnect.MainActivity$AsyncTest.doInBackground(MainActivity.java:1)
在android.os.AsyncTask$2.call(AsyncTask.java:287)
在java.util.concurrent.FutureTask.run(FutureTask.java:234)处
... 4更多
原因:java.net.SocketTimeoutException:90000毫秒后无法连接到/192.168.0.13(端口4040)
在libcore.io.IoBridge.ConnecterNo(IoBridge.java:176)中
在libcore.io.IoBridge.connect上(IoBridge.java:112)
在libcore.io.IoBridge.connect上(IoBridge.java:100)
... 9更多
A无法找到捕获此异常的方法,该应用程序已被操作系统关闭。虽然超时不是正常情况,但我应该能够检测到超时并向用户显示错误消息,而不仅仅是崩溃
连接成功的情况在所有设备中都可以正常工作
编辑:第一段错误地提到Android 2.4而不是4.2.2
编辑:根据Jarred的建议简化代码并添加附加信息
更新:在安卓4.4.4设备上测试,效果良好。我将把它作为Android 4.2.2的一个bug关闭(可能在这个特定的设备上)。删除大部分:
您正在从另一个线程开始线程
。只需使用异步任务
从主线程
启动一个线程
protected View.OnClickListener doTest = new View.OnClickListener() {
@Override
public void onClick(View v) {
new Thread(new threadTest()).start();
}
};
private class threadTest implements Runnable {
@Override
public void run() {
try {
runOnUiThread(new Runnable() {
@Override
public void run() {
new AsyncTest().execute();
}
});
} catch (Exception e) {
Log.e(TAG, e.getMessage());
}
}
}
将其更改为:
对于异常和超时:
IOException
是SocketTimeoutException
的父类,因此您的AsyncTask
代码应该可以工作。当有疑问时,您可以通过使用Exception
捕获所有内容
需要检查的其他事项:
- 你能打192.168.0.13吗
- 你怎么知道那个端口是开放的?试试telnet或netcat
- 您是否在端口上正确运行和配置了服务
- 你有正确的Android权限吗
尝试捕获导致错误的上述异常:catch(SocketTimeoutException e)
@Willis我已经尝试过了,但没有成功。毫不奇怪,因为SocketTimeoutException是IOException的后代。@dquadros您能试试我的答案吗?我也有一个类似的(同样荒谬的)问题,原因是他们更改了类/接口层次结构,但没有在文档中反映出来。我建议设置\u设备的目标\u API=minimal\u API=API\u,看看它是否工作。另外两个选项是捕获throwable和设置未经处理的异常处理程序。主要的一点是,当连接超时时,代码不起作用。如问题中所述,我有意测试一个封闭端口。该应用程序具有互联网权限,如果不考虑这一点,则会出现一个非常特殊的例外。关于多余的任务,它们来自原始代码I(粗略地)简化。我将尝试您的版本,但它不应与崩溃问题相关,而应捕获超时异常。我已在回答中用新的简化代码说明了要点,并建议改用异常。线程的调用方式肯定会在将来给您带来问题。明天我将尝试您的代码,我已经尝试使用Exception,但结果相同。别担心,我会在这里告诉你结果的。我喜欢简化的代码,如果没有新的问题,但问题仍然存在,我将更新问题以关注主要问题。最初的代码已经在安卓2.x和3.x的数十台设备上运行了数年(但超时情况可能没有发生过很多次)。很少看到3.x设备。很快,您就可以以4.0+为目标,因为2.x非常罕见,因为它太旧了。@Jarred Burrows在更新的问题上指出,问题仍然存在于简化(更好)的代码中。是的,3.x很少见,2.x很旧,但这是一个旧的应用程序,我的用户仍然在使用它们。但他们想开始使用4.x设备,而这正是这一切的开始。无论如何,这个问题似乎是针对这个Android版本的,我会按照你的建议进行编码。谢谢你的帮助!
protected View.OnClickListener doTest = new View.OnClickListener() {
@Override
public void onClick(View v) {
new AsyncTest().execute();
}
};