簡體   English   中英

Android:使用簡單的警報對話框處理AsyncTask中的SocketTimeoutException

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

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM