[英]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.