[英]Android: Handling SocketTimeoutException inside AsyncTask with a simple Alert Dialog
I use AsyncTask in my Android app to fetch some data from a server. 我在Android应用程序中使用AsyncTask从服务器获取一些数据。 To make the connection, I use the HttpURLConnection class with a timeout of 10 seconds. 要建立连接,我使用HttpURLConnection类,超时为10秒。 Now, I would like to show a simple AlertDialog when (if) that time expires, with an OK button that takes the user back to Main Activity. 现在,我想在(如果)该时间到期时显示一个简单的AlertDialog,使用OK按钮将用户带回到Main Activity。 Right now, this is what the relevant part of my app (DoorActivity) looks like: 现在,这就是我的应用程序(DoorActivity)的相关部分:
protected String doInBackground(String... params) {
try {
URL url = new URL(params[0]);
urlConnection = (HttpURLConnection) url.openConnection();
urlConnection.setConnectTimeout(10000);
urlConnection.setRequestMethod("GET");
if (urlConnection.getResponseCode() != 200) {
throw new IOException(urlConnection.getResponseMessage());
}
BufferedReader read = new BufferedReader(new InputStreamReader(urlConnection.getInputStream()));
jsonString = read.readLine().toString();
} catch (MalformedURLException malformedUrlException) {
System.out.println(malformedUrlException.getMessage());
malformedUrlException.printStackTrace();
} catch (SocketTimeoutException connTimeout) {
showTimeoutAlert();
showTimeoutAlert() method is located in the root class of DoorActivity, and looks like this: showTimeoutAlert()方法位于DoorActivity的根类中,如下所示:
protected void showTimeoutAlert(){
TextView timeoutWarning = new TextView(this);
AlertDialog.Builder builder = new AlertDialog.Builder(this);
AlertDialog alertDialog;
timeoutWarning.setText(R.string.conn_timeout_warning);
builder.setView(timeoutWarning);
builder.setPositiveButton("OK", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
Intent intent = new Intent(DoorActivity.this, MainActivity.class);
startActivity(intent);
}
});
alertDialog = builder.create();
alertDialog.show();
}
Now, when I run this app, with the server deliberately offline, I get the following exception: 现在,当我运行此应用程序时,服务器故意脱机,我得到以下异常:
java.lang.RuntimeException: An error occured while executing doInBackground() java.lang.RuntimeException:执行doInBackground()时发生错误
Caused by: java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare() 引起:java.lang.RuntimeException:无法在未调用Looper.prepare()的线程内创建处理程序
showTimeoutAlert();
should not be called in doInBackground()
. 不应该在doInBackground()
调用。 Any code related to UI should go in onPostExecute()
instead. 任何与UI相关的代码都应该放在onPostExecute()
。
For example: 例如:
private boolean socketTimedOut = false;
@Override
protected String doInBackground(String... params) {
try {
...
} catch (SocketTimeoutException connTimeout) {
this.socketTimedOut = true;
}
}
@Override
protected void onPostExecute(String result) {
if(this.socketTimedOut){
showTimeoutAlert();
}
}
Alternative solution (not recommended): 替代解决方案(不推荐):
@Override
protected String doInBackground(String... params) {
try {
...
} catch (SocketTimeoutException connTimeout) {
runOnUiThread(new Runnable() {
public void run() {
showTimeoutAlert();
}
});
}
}
You can not show popups/dialogs within doInBackground method. 您无法在doInBackground方法中显示弹出窗口/对话框。 Return null if you get any exceptions and check the return in postExecute method. 如果出现任何异常,则返回null并检查postExecute方法中的返回值。 There you can show the relevant popup/dialogs 在那里,您可以显示相关的弹出/对话框
You have to call showTimeoutAlert() in the postExecute method because you cannot change the UI in the doInBackground dialog. 您必须在postExecute方法中调用showTimeoutAlert(),因为您无法在doInBackground对话框中更改UI。 Return a relsut and then call the method there. 返回一个relsut,然后在那里调用该方法。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.