[英]Android: Handling SocketTimeoutException inside AsyncTask with a simple Alert Dialog
我在Android应用程序中使用AsyncTask从服务器获取一些数据。 要建立连接,我使用HttpURLConnection类,超时为10秒。 现在,我想在(如果)该时间到期时显示一个简单的AlertDialog,使用OK按钮将用户带回到Main Activity。 现在,这就是我的应用程序(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()方法位于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();
}
现在,当我运行此应用程序时,服务器故意脱机,我得到以下异常:
java.lang.RuntimeException:执行doInBackground()时发生错误
引起:java.lang.RuntimeException:无法在未调用Looper.prepare()的线程内创建处理程序
showTimeoutAlert();
不应该在doInBackground()
调用。 任何与UI相关的代码都应该放在onPostExecute()
。
例如:
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();
}
}
替代解决方案(不推荐):
@Override
protected String doInBackground(String... params) {
try {
...
} catch (SocketTimeoutException connTimeout) {
runOnUiThread(new Runnable() {
public void run() {
showTimeoutAlert();
}
});
}
}
您无法在doInBackground方法中显示弹出窗口/对话框。 如果出现任何异常,则返回null并检查postExecute方法中的返回值。 在那里,您可以显示相关的弹出/对话框
您必须在postExecute方法中调用showTimeoutAlert(),因为您无法在doInBackground对话框中更改UI。 返回一个relsut,然后在那里调用该方法。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.