Android: how to handle error in try catch without forced closure

When I run asynctask to connect to an HTTP server, I want to display an error message when it cannot connect to the server. Instead, the application is forced to close on error without displaying an error message. I want to display an error message when an error occurs, not a crash, but it just shows an error message dialog (e.getMessage ()) in the body state alert dialog.

Below is my code:

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 error:

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 verbose 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)

      

Thank.

+3


source to share


5 answers


Start your dialog separately from the UI thread. Just try this way:



 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);
        }
    }
    }

      

+2


source


as in log:

RuntimeException: Cannot create a handler inside a thread that is not called Looper.prepare ()



because you are trying to show an AlertDialog from AsyncTask doInBackground and we cannot update UI elements from doInBackground method. change your code to handle execution in 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);
        }
}

      

+3


source


 ErrorDialog(e.getMessage());

      

you cannot invoke alert dialog inside doInBackground () .

so the Alternativce way puts a global variable of type XYZ inside the Asyc class and sets e.getMessage () to that variable XYZ inside the catch block. and check if this variable is empty or not and execute the command ErrorDialog (XYZ); inside the onPostExecute () method.

Hope this helps you.

+2


source


You cannot directly display the alert dialog from doinbackground (). You need to call it from runOnUIThread () or call from postExecute () or send a message to the activity handler.

+2


source


Urlconnection has a setTimeout method. Catch it with a SocketTimeOutException (which will be thrown back to the caller). Toast it.

0


source







All Articles