2016-05-17 82 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)上串行執行,因此長時間運行的工作人員可以阻止其他人;