简体   繁体   中英

How can I ensure an AsyncTask is completed before my activity is killed?

I'm getting an Unable to destroy activity xxx: android.database.sqlite.SQLiteException: unable to close due to unfinalised statements error while my activity is being destroyed. I presume this is because I'm performing database operations from within AsyncTasks and they are somehow being killed before completion.

How can I ensure that my AsyncTasks actually complete before the activity is stopped? Incidentally, I thought that an AsyncTask can't be explicitly killed without the AsyncTask agreeing to do so by checking.

It may be relevant that this error is occurring during Robotium integration testing. I suspect it's happening after the test is completed and the test calls Robotium.finishOpenedActivities() . My guess is that somehow the AsyncTask is being forcefully killed mid-execution if this is possible (though I don't explcitly support cancellation in my AsyncTask implementation). Additionally, I use OrmLite for my database access.

看起来如果我在我的活动中覆盖onPause()事件,并且在重写的onPause() ,我在AsyncTasks上调用cancel(false) ,那么在AsyncTasks完成之前不会销毁活动。

You can check AsyncTask.getStatus() against AsyncTask.Status.RUNNING at any time.

Perhaps you need to make your activity and your AsyncTask aware of each other as was asked in this question Is AsyncTask really conceptually flawed or am I just missing something? and the answer by @hackbod explains exactly how

There are several things you can do here:

  1. Override these methods and see determine exactly what state the object is in when it is closed. It seems that onPostExecute is going to get called when the AsyncTask is done. If it has not been called its too early.

     protected void onProgressUpdate(Integer... progress) { setProgressPercent(progress[0]); } protected void onPostExecute(Long result) { } 
  2. You can also execute as follows:

     // with THREAD_POOL_EXECUTOR. executeOnExecutor(java.util.concurrent.Executor, Object[]) 
  3. Make sure you are following the first two rules in the documentation: Are you following 1 and 2?

    There are a few threading rules that must be followed for this class to work properly:

    1. The AsyncTask class must be loaded on the UI thread. This is done automatically as of JELLY_BEAN.

    2. The task instance must be created on the UI thread.

    3. execute(Params...) must be invoked on the UI thread.

    4. Do not call onPreExecute(), onPostExecute(Result), doInBackground(Params...), onProgressUpdate(Progress...) manually.

    5. The task can be executed only once (an exception will be thrown if a second execution is attempted.)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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