简体   繁体   English

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

[英]How to gracefully handle exception inside AsyncTask in Android?

I have an AsyncTask to do SQLite database migration in the background (create or upgrade). 我有一个AsyncTask在后台进行SQLite数据库迁移(创建或升级)。 Let's say somehow an IOException or SQLiteException is thrown inside doInBackground and it's pointless for the app to continue running because database state might be not in desired state. 比方说,不知何故一个IOExceptionSQLiteException是内部doInBackground抛出这是毫无意义的应用程序继续运行,因为数据库的状态可能会在理想状态是不。 I'm kind of confused on what to do in this situation. 我对在这种情况下该怎么做感到困惑。

I'm thinking about letting the application crash as soon as possible and show dialog with error message, but I'm not really sure how to this inside doInBackground , because: 我正在考虑让应用程序尽快崩溃并显示错误消息的对话框,但我不确定如何在doInBackground内部,因为:

  1. This function is not executed in UI thread so I don't know if I can show a dialog. 此功能不在UI线程中执行,因此我不知道是否可以显示对话框。
  2. I don't know how to access current activity within AsyncTask , so I can't finish() it. 我不知道如何访问AsyncTask中的当前活动,所以我无法完成()它。
  3. I want to somehow throw the exception to the upper layer and let an activity handle it, but it's not possible because doInBackground doesn't list IOException as a checked exception. 我想以某种方式将异常抛出到上层并让一个活动处理它,但这是不可能的,因为doInBackground不会将IOException列为已检查的异常。

Anyone has an advice on how to gracefully handle this situation? 任何人都有关于如何优雅地处理这种情况的建议?

You can't show dialog in non-ui thread. 您无法在非ui线程中显示对话框。 You can pass activity reference to async task. 您可以将活动引用传递给异步任务。 To handle this situation you can try catch the exception in doInBackground and re-throw it in onPostExecute 要处理这种情况,您可以尝试捕获doInBackground中的异常并将其重新抛入onPostExecute

eg 例如

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

If you async task is in Acvitiy class, then you can directly access it, eg, 如果您的异步任务在Acvitiy类中,那么您可以直接访问它,例如,

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

return a unique string everytime such an exception occurs in doInBackground to onPostExecute. 每次在doInBackground中发生onPostExecute时都会返回一个唯一的字符串。 and in onPostExecute display a AlertDialog showing appropriate message and ask to try again or something. 并在onPostExecute中显示一个AlertDialog,显示相应的消息并要求再次尝试。

My approach to handle it. 我处理它的方法。

/**
 * 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);

}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM