Android: как обрабатывать ошибку в try catch без принудительного закрытия

Когда я запускаю 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 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) 

Благодарю.

Запустите свой диалог отдельно от потока пользовательского интерфейса. Просто попробуйте:

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

Как в журнале:

RuntimeException: невозможно создать обработчик внутри потока, который не вызвал Looper.prepare ()

Потому что вы пытаетесь показать AlertDialog из doInBackground AsyncTask, и мы не можем обновлять элементы пользовательского интерфейса из метода doInBackground. Измените свой код, чтобы обрабатывать выполнение в 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); } } 
  ErrorDialog(e.getMessage()); 

Вы не можете вызвать диалог оповещений внутри doInBackground () .

Поэтому способ Alternativce устанавливает глобальную переменную типа XYZ внутри класса Asyc и устанавливает e.getMessage () в этот переменный XYZ внутри блока catch. И проверить, является ли эта переменная пустой или нет, и выполнить команду ErrorDialog (XYZ); Внутри onPostExecute () способ.

Надеюсь, это поможет вам.

Вы не можете напрямую отображать диалоговое окно предупреждения из doinbackground (). Вам нужно вызвать его из runOnUIThread () или вызвать из postExecute () или отправить сообщение обработчику активности.

Urlconnection имеет метод setTimeout. Поймайте его с помощью SocketTimeOutException (которое будет отброшено обратно вызывающему абоненту). Обращайтесь с тостом.