2016-05-17 106 views
0

通常,我有一个AsyncTask我想取消它。在其doInBackground方法中,我有几个Thread.sleep方法,他们之间我检查是否AsyncTask#cancelisCancelled()调用。取消AsyncTask遇到Thread.sleep

这里的问题:如果我在doInBackground方法有Thread.sleep,该AsyncTask#onCancelled()将不会被调用。如果所有Thread.sleep都被删除,则调用AsyncTask#onCancelled()什么使这发生

这是演示的定义。

inner class DemoAsyncTask() : AsyncTask<String, Int, String>() { 
    //  var isRunning = true 
    override fun doInBackground(vararg params: String?): String? { 
     Log.i(TAG, "##AsyncTask doing something...") 

     var i = 0 
     val TOTAL = 100000000 
     var progress = 0 
     while (i < TOTAL && !isCancelled) { 
      Log.d(TAG, "doning jobs $i is cancelled $isCancelled") 
      i++ 

      var currentProgress = i/TOTAL 
      if (currentProgress > progress) { 
       progress = currentProgress 
       publishProgress(progress) 
      } 
     } 

     Log.d(TAG, "doning jobs $i is cancelled $isCancelled") 

     return "Task done" 
    } 

    override fun onPostExecute(result: String?) { 
     [email protected]?.text = result 
    } 

    override fun onProgressUpdate(vararg values: Int?) { 
     mAsyncTextView?.text = "${mAsyncTextView?.text ?: "Async task..."} progress: ${values?.get(0) ?: 0}" 
    } 

    override fun onCancelled() { 
     Log.i(TAG, "##Task cancelled") 
//   isRunning = false 
     [email protected]?.text = "###Task cancelled" 
    } 
} 

doInbackground可以工作,这原来问题出在哪里发生的这个样子的:

if (isCancelled) { 
    var msg = mHandler.obtainMessage(THREAD_CANCELLED) 
    mHandler.sendMessage(msg) 
    return 
} 

Thread.sleep(2000) 

if (isCancelled) { 
    var msg = mHandler.obtainMessage(THREAD_CANCELLED) 
    mHandler.sendMessage(msg) 
    return 
} 

var msg = mHandler.obtainMessage(THREAD_FINISHED) 
mHandler.sendMessage(msg) 

谢谢!

回答

0

不能重现纯Java(API 23)你的问题,这里是日志:

I/NSA: doInBackground 0 
I/NSA: doInBackground 1 
I/NSA: wait 2 sec and cancel 
W/System.err: java.lang.InterruptedException 
I/NSA: should be cancelled 
W/art: Suspending all threads took: 15.850ms 
W/System.err:  at java.lang.Thread.sleep(Native Method) 
W/System.err:  at java.lang.Thread.sleep(Thread.java:1031) 
W/System.err:  at java.lang.Thread.sleep(Thread.java:985) 
W/System.err:  at org.dodroid.test_dialog.AsyncTaskX.doInBackground(AsyncTaskX.java:19) 
W/System.err:  at org.dodroid.test_dialog.AsyncTaskX.doInBackground(AsyncTaskX.java:7) 
W/System.err:  at android.os.AsyncTask$2.call(AsyncTask.java:295) 
W/System.err:  at java.util.concurrent.FutureTask.run(FutureTask.java:237) 
W/System.err:  at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:234) 
W/System.err:  at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1113) 
W/System.err:  at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:588) 
W/System.err:  at java.lang.Thread.run(Thread.java:818) 
I/NSA: doInBackground 2 
D/OpenGLRenderer: Use EGL_SWAP_BEHAVIOR_PRESERVED: true 
I/Adreno-EGL: <qeglDrvAPI_eglInitialize:379>: QUALCOMM Build: 10/21/15, 369a2ea, I96aee987eb 
I/OpenGLRenderer: Initialized EGL, version 1.4 
I/NSA: task was cancelled, sending message 
I/NSA: handleMessage 
I/NSA: onCancelled 

您可以考虑的另一种架构(看服务),因为有一些缺点:

  • AsyncTask只能用于需要几秒钟的任务;

  • AsyncTasks在单个后台线程(来自API 11)上串行执行,因此长时间运行的工作人员可以阻止其他人;