3

asynctask を実行して HTTP サーバーに接続するときに、サーバーに接続できないときにエラー メッセージを表示したいと考えています。代わりに、アプリはエラー メッセージを表示せずに強制的に終了します。クラッシュではなくエラー発生時にエラーメッセージを表示したいのですが、本文説明アラートダイアログにエラー(e.getMessage())というメッセージのアラートダイアログが表示されるだけです。

以下は私のコードです:

private String downloadUrl(String strUrl) throws IOException {
    String data = "";
    InputStream iStream = null;
    try {
        URL url = new URL(strUrl);

        HttpURLConnection urlConnection = (HttpURLConnection) url
            .openConnection();

        urlConnection.connect();
        iStream = urlConnection.getInputStream();

        BufferedReader br = new BufferedReader(new InputStreamReader(
            iStream));

        StringBuffer sb = new StringBuffer();

        String line = "";
        while ((line = br.readLine()) != null) {
            sb.append(line);
        }
        data = sb.toString();
        br.close();
    } catch (IOException e) {
        Log.d(TAG, e.getMessage());
        ErrorDialog(e.getMessage());
    }

    return data;
 }

private class DownloadTask extends AsyncTask<String, Integer, String> {
    String data = null;

    @Override
    protected String doInBackground(String... url) {
        try {
            data = downloadUrl(url[0]);
        } catch (IOException e) {
            Log.d(TAG, e.getMessage());
            ErrorDialog(e.getMessage());
        }

        return data;
    }

    @Override
    protected void onPostExecute(String result) {
        if (result != null && result.length() < 0) {
            ListViewLoaderTask listViewLoaderTask = new ListViewLoaderTask();
            listViewLoaderTask.execute(result);
        }
    }
}

private void ErrorDialog(String Description) {
    AlertDialog.Builder alertDialog = new AlertDialog.Builder(
            ListCategoryActivity.this);
    alertDialog.setTitle("You get Error...");
    alertDialog.setMessage(Description);
    alertDialog.setIcon(R.drawable.ic_warning);

    alertDialog.setNegativeButton("Cancel",
            new DialogInterface.OnClickListener() {
                public void onClick(DialogInterface dialog, int which) {
                    dialog.cancel();
                }
            });

    alertDialog.show();
}

Logcat エラー:

01-23 11:58:36.949: E/AndroidRuntime(5776): FATAL EXCEPTION: AsyncTask #1
01-23 11:58:36.949: E/AndroidRuntime(5776): java.lang.RuntimeException: An error occured while executing doInBackground()
01-23 11:58:36.949: E/AndroidRuntime(5776):     at android.os.AsyncTask$3.done(AsyncTask.java:278)
01-23 11:58:36.949: E/AndroidRuntime(5776):     at java.util.concurrent.FutureTask$Sync.innerSetException(FutureTask.java:273)
01-23 11:58:36.949: E/AndroidRuntime(5776):     at java.util.concurrent.FutureTask.setException(FutureTask.java:124)
01-23 11:58:36.949: E/AndroidRuntime(5776):     at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:307)
01-23 11:58:36.949: E/AndroidRuntime(5776):     at java.util.concurrent.FutureTask.run(FutureTask.java:137)
01-23 11:58:36.949: E/AndroidRuntime(5776):     at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:208)
01-23 11:58:36.949: E/AndroidRuntime(5776):     at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1076)
01-23 11:58:36.949: E/AndroidRuntime(5776):     at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:569)
01-23 11:58:36.949: E/AndroidRuntime(5776):     at java.lang.Thread.run(Thread.java:856)
01-23 11:58:36.949: E/AndroidRuntime(5776): Caused by: java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare()
01-23 11:58:36.949: E/AndroidRuntime(5776):     at android.os.Handler.<init>(Handler.java:121)
01-23 11:58:36.949: E/AndroidRuntime(5776):     at android.app.Dialog.<init>(Dialog.java:107)
01-23 11:58:36.949: E/AndroidRuntime(5776):     at android.app.AlertDialog.<init>(AlertDialog.java:114)
01-23 11:58:36.949: E/AndroidRuntime(5776):     at android.app.AlertDialog$Builder.create(AlertDialog.java:913)
01-23 11:58:36.949: E/AndroidRuntime(5776):     at android.app.AlertDialog$Builder.show(AlertDialog.java:931)
01-23 11:58:36.949: E/AndroidRuntime(5776):     at com.haichal.codefive.ListCategoryActivity.ErrorDialog(ListCategoryActivity.java:327)
01-23 11:58:36.949: E/AndroidRuntime(5776):     at com.haichal.codefive.ListCategoryActivity.downloadUrl(ListCategoryActivity.java:150)
01-23 11:58:36.949: E/AndroidRuntime(5776):     at com.haichal.codefive.ListCategoryActivity.access$2(ListCategoryActivity.java:125)
01-23 11:58:36.949: E/AndroidRuntime(5776):     at com.haichal.codefive.ListCategoryActivity$DownloadTask.doInBackground(ListCategoryActivity.java:162)
01-23 11:58:36.949: E/AndroidRuntime(5776):     at com.haichal.codefive.ListCategoryActivity$DownloadTask.doInBackground(ListCategoryActivity.java:1)
01-23 11:58:36.949: E/AndroidRuntime(5776):     at android.os.AsyncTask$2.call(AsyncTask.java:264)
01-23 11:58:36.949: E/AndroidRuntime(5776):     at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:305)
01-23 11:58:36.949: E/AndroidRuntime(5776):     ... 5 more
01-23 11:58:38.079: E/WindowManager(5776): Activity com.haichal.codefive.ListCategoryActivity has leaked window com.android.internal.policy.impl.PhoneWindow$DecorView@41410d58 that was originally added here
01-23 11:58:38.079: E/WindowManager(5776): android.view.WindowLeaked: Activity com.haichal.codefive.ListCategoryActivity has leaked window com.android.internal.policy.impl.PhoneWindow$DecorView@41410d58 that was originally added here
01-23 11:58:38.079: E/WindowManager(5776):  at android.view.ViewRootImpl.<init>(ViewRootImpl.java:344)
01-23 11:58:38.079: E/WindowManager(5776):  at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:267)
01-23 11:58:38.079: E/WindowManager(5776):  at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:215)
01-23 11:58:38.079: E/WindowManager(5776):  at android.view.WindowManagerImpl$CompatModeWrapper.addView(WindowManagerImpl.java:140)
01-23 11:58:38.079: E/WindowManager(5776):  at android.view.Window$LocalWindowManager.addView(Window.java:537)
01-23 11:58:38.079: E/WindowManager(5776):  at android.app.Dialog.show(Dialog.java:278)
01-23 11:58:38.079: E/WindowManager(5776):  at com.haichal.codefive.ListCategoryActivity.startDownload(ListCategoryActivity.java:100)
01-23 11:58:38.079: E/WindowManager(5776):  at com.haichal.codefive.ListCategoryActivity.initFromDb(ListCategoryActivity.java:91)
01-23 11:58:38.079: E/WindowManager(5776):  at com.haichal.codefive.ListCategoryActivity.onCreate(ListCategoryActivity.java:54)
01-23 11:58:38.079: E/WindowManager(5776):  at android.app.Activity.performCreate(Activity.java:4465)
01-23 11:58:38.079: E/WindowManager(5776):  at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1049)
01-23 11:58:38.079: E/WindowManager(5776):  at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1923)
01-23 11:58:38.079: E/WindowManager(5776):  at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1984)
01-23 11:58:38.079: E/WindowManager(5776):  at android.app.ActivityThread.access$600(ActivityThread.java:126)
01-23 11:58:38.079: E/WindowManager(5776):  at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1150)
01-23 11:58:38.079: E/WindowManager(5776):  at android.os.Handler.dispatchMessage(Handler.java:99)
01-23 11:58:38.079: E/WindowManager(5776):  at android.os.Looper.loop(Looper.java:137)
01-23 11:58:38.079: E/WindowManager(5776):  at android.app.ActivityThread.main(ActivityThread.java:4456)
01-23 11:58:38.079: E/WindowManager(5776):  at java.lang.reflect.Method.invokeNative(Native Method)
01-23 11:58:38.079: E/WindowManager(5776):  at java.lang.reflect.Method.invoke(Method.java:511)
01-23 11:58:38.079: E/WindowManager(5776):  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:787)
01-23 11:58:38.079: E/WindowManager(5776):  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:554)
01-23 11:58:38.079: E/WindowManager(5776):  at dalvik.system.NativeStart.main(Native Method)

Logcat 詳細 e.getMessage();

01-23 11:58:36.909: D/HaichalLog(5776): failed to connect to 
  /192.168.103.121 (port 80): connect failed: ENETUNREACH (Network is unreachable)

ありがとう。

4

5 に答える 5

3

ログのように:

RuntimeException: Looper.prepare() を呼び出していないスレッド内でハンドラーを作成できません

AsyncTask の doInBackground から AlertDialog を表示しようとしており、doInBackground メソッドから UI 要素を更新できないためです。doInBackground で実行を処理するようにコードを変更します。

String strcatcherror="";
@Override
protected String doInBackground(String... url) {
    try {
        data = downloadUrl(url[0]);
        strcatcherror="";
    } catch (IOException e) {
        Log.d(TAG, e.getMessage());
        strcatcherror=e.getMessage();

    }

    return data;
}

@Override
protected void onPostExecute(String result) {
    if(!strcatcherror.equals("")){
         if (result != null && result.length() < 0) {
           ListViewLoaderTask listViewLoaderTask = new ListViewLoaderTask();
           listViewLoaderTask.execute(result);
         }
       }
     else{
             // show error message here
             ErrorDialog(strcatcherror);
        }
}
于 2013-01-23T05:17:27.733 に答える
2
 ErrorDialog(e.getMessage());

doInBackground() 内でアラートダイアログを呼び出すことはできません。

そのため、代替方法は、Asyc クラス内に XYZ のようなグローバル変数を配置し、e.getMessage() を catch ブロック内のその変数 XYZ に設定します。その変数が空かどうかを確認し、ErrorDialog(XYZ) を実行します。onPostExecute() メソッド内。

それがあなたを助けることを願っています。

于 2013-01-23T05:17:50.667 に答える
2

doinbackground() から警告ダイアログを直接表示することはできません。runOnUIThread() から呼び出すか、postExecute() から呼び出すか、メッセージをアクティビティ ハンドラに送信する必要があります。

于 2013-01-23T05:55:31.243 に答える
2

ダイアログを UI スレッドとは別に実行します。次の方法を試してみてください。

 private class DownloadTask extends AsyncTask<String, Integer, String> {
    String data = null;
    @Override
    protected String doInBackground(String... url) {
       try {
            data = downloadUrl(url[0]);
          } catch (IOException e) {
           Log.d(TAG, e.getMessage());
        runOnUiThread(new Runnable(){
          public void run() {
                 ErrorDialog(e.getMessage());
                }
     });
    }
}
        return data;
    }
    @Override
    protected void onPostExecute(String result) {
        if (result != null && result.length() < 0) {
            ListViewLoaderTask listViewLoaderTask = new ListViewLoaderTask();
            listViewLoaderTask.execute(result);
        }
    }
    }
于 2013-01-23T05:30:49.763 に答える