如何在Android中的AsyncTask中优雅地处理异常?

我有一个AsyncTask在后台执行sqlite数据库迁移(创建或升级).假设某种方式会在doInBackground中抛出一个IOException或sqliteException,并且由于数据库状态可能不在期望的状态,应用程序继续运行是毫无意义的.在这种情况下,我有什么困难的.

我正在考虑让应用程序尽快崩溃并显示带有错误消息的对话框,但是我不太确定如何在doInBackground里面,因为:

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

任何人都有如何正确处理这种情况的建议?

解决方法

您不能在非ui线程中显示对话框.您可以将活动引用传递给异步任务.为了处理这种情况,你可以尝试在doInBackground中捕获异常并重新抛出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;
         }
     }
 }

如果异步任务在Acvitiy类中,那么您可以直接访问它,例如,

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

相关文章

以下为个人理解,如错请评 CE: 凭据加密 (CE) 存储空间, 实际路径/data/user_ce/ DE: 设备加密 (DE) 存...
转载来源:https://blog.csdn.net/yfbdxz/article/details/114702144 用EventLog.writeEvent打的日志(或...
事件分发机制详解 一、基础知识介绍 1、经常用的事件有:MotionEvent.ACTION_DOWN,MotionEvent.ACTION...
又是好久没有写博客了,一直都比较忙,最近终于有时间沉淀和整理一下最近学到和解决的一些问题。 最近进...
Android性能优化——之控件的优化 前面讲了图像的优化,接下来分享一下控件的性能优化,这里主要是面向...
android的开源库是用来在android上显示gif图片的。我在网上查了一下,大家说这个框架写的不错,加载大的...