如何在Android中正常处理AsyncTask中的exception?

我有一个AsyncTask在后台执行SQLite数据库迁移(创build或升级)。 比方说,在doInBackground内部抛出一个IOException或者SQLiteException,并且由于数据库状态可能不处于期望的状态,应用程序继续运行是毫无意义的。 我对这种情况下做什么感到困惑。

我正在考虑让应用程序尽快崩溃,并显示对话框的错误消息,但我不知道如何在doInBackground这里 ,因为:

  1. 这个函数不会在UI线程中执行,所以我不知道是否可以显示对话框。
  2. 我不知道如何访问AsyncTask中的当前活动,所以我不能完成()它。
  3. 我想以某种方式抛出exception到上层,让一个活动处理它,但这是不可能的,因为doInBackground不会列出IOException作为检查的exception。

任何人都有如何妥善处理这种情况的build议?

Solutions Collecting From Web of "如何在Android中正常处理AsyncTask中的exception?"

你不能在非UI线程中显示对话框。 您可以将活动引用传递给asynchronous任务。 要处理这种情况,你可以尝试在doInBackground中捕获exception,并将其重新抛出onPostExecute

例如

private class MyAsyncTaskTask extends AsyncTask<...> { private Activity ownerActivity; private Exception exceptionToBeThrown; public MyAsyncTaskTask(Activity activity) { // keep activity reference this.ownerActivity = activity; } protected Long doInBackground(...) { try { ... } catch (Exception e) { // save exception and re-thrown it then. exceptionToBeThrown = e; } } protected void onPostExecute(...) { // Check if exception exists. if (exceptionToBeThrown != null) { ownerActivity.handleXXX(); throw exceptionToBeThrown; } } } 

如果你的asynchronous任务是在Acvitiy类,那么你可以直接访问它,例如,

 public class MyActivity extends Activity { ... AsyncTask<...> task = new AsyncTask<...>() { public void onPostExecute(...) { // Access activity directly MyActivity.this.xxx() } } } 

每次在doInBackground到onPostExecute中都会发生这样的exception。 并在onPostExecute显示AlertDialog显示适当的消息,并要求再试一次。

我的方法来处理它。

 /** * Created by Daniel on 02/04/2016. */ public abstract class AsyncTaskEnhanced<Params, Progress, Result> extends AsyncTask<Params, Progress, Result> { // Avoids cyclic calls. private boolean onPostExecuteCalled = false; private Exception exception; @Override protected final Result doInBackground(Params... params) { try { return this.doInBackgroundWithFaultTolerance(params); } catch (Exception exception) { this.exception = nre; } return null; } @Override protected final void onPostExecute(Result result) { if (this.onPostExecuteCalled) return; this.onPostExecuteCalled = true; super.onPostExecute(result); this.onPostExecuteWithFaultTolerance(result, this.exception); } protected abstract Result doInBackgroundWithFaultTolerance(Params... params) throws Exception; protected abstract void onPostExecuteWithFaultTolerance(Result result, Exception ex); }