2012-04-15 9 views
7

doInBackground()'dan içinden arama yaptıktan sonra,numaralı telefonu çağırmak yerine, Android onPostExecute() numaralı telefonu çağırır. Ama as per the documentation: onCancelled(Object) sonuçlanacaktır Bu yöntemin çağrılmasıAysncTask kendini hala iptal ediyorPostExecute()

doInBackground(Object[]) döndükten sonra UI iş parçacığı üzerinde çağrı yapılmaktadır. Bu yönteminin çağrılması, onPostExecute(Object) numaralı telefonun hiçbir zaman çağrılmadığını garanti eder.

Android'de bir hata mı?

Daha Gözlemler: belgesinde belirtilen şekilde ya parçacığı çalışır dan cancel(false) çağrılması

  1. . UI görevden cancel(true) çağrılması
  2. değil çağrı onPostExecute() yapar, ne de LogCat görülen InterruptedException aşağıda izleri atmak yok.
  3. Herhangi bir iş parçacığından cancel(false/true) numaralı telefonu arayarak doInBackground() geri dönmeden önce bile onCancelled()'u çağırır. Bu, açıkça belgelerin ihlal which states geçerli: onCancelled (Object) sonuçlanacaktır Bu yöntemin çağrılması

doInBackground(Object[]) getiri sonra UI iş parçacığı üzerinde çağrı yapılmaktadır.

Kodu: (Android 2.2 cihazda test edilmiştir)

protected Void doInBackground(Void... params) { 
    Log.d(TAG, "started doInBackground()"); 
    while (!isCancelled()) { 
     boolean ret = cancel(true); 
     Log.d(TAG, "cancel() returned: " + ret); 
    } 
    Log.d(TAG, "returning from doInBackground()"); 
    return null; 
} 

Logcat çıkışı

04-15 21:38:55.519: D/MyTask(27597): started doInBackground() 
04-15 21:38:55.589: W/AsyncTask(27597): java.lang.InterruptedException 
04-15 21:38:55.589: W/AsyncTask(27597):  at java.util.concurrent.locks.AbstractQueuedSynchronizer.acquireSharedInterruptibly(AbstractQueuedSynchronizer.java:1254) 
04-15 21:38:55.589: W/AsyncTask(27597):  at java.util.concurrent.FutureTask$Sync.innerGet(FutureTask.java:219) 
04-15 21:38:55.589: W/AsyncTask(27597):  at java.util.concurrent.FutureTask.get(FutureTask.java:82) 
04-15 21:38:55.589: W/AsyncTask(27597):  at android.os.AsyncTask$3.done(AsyncTask.java:196) 
04-15 21:38:55.589: W/AsyncTask(27597):  at java.util.concurrent.FutureTask$Sync.innerCancel(FutureTask.java:293) 
04-15 21:38:55.589: W/AsyncTask(27597):  at java.util.concurrent.FutureTask.cancel(FutureTask.java:75) 
04-15 21:38:55.589: W/AsyncTask(27597):  at android.os.AsyncTask.cancel(AsyncTask.java:325) 
04-15 21:38:55.589: W/AsyncTask(27597):  at com.example.test.TestActivity$MyTask.doInBackground(TestActivity.java:31) 
04-15 21:38:55.589: W/AsyncTask(27597):  at com.example.test.TestActivity$MyTask.doInBackground(TestActivity.java:1) 
04-15 21:38:55.589: W/AsyncTask(27597):  at android.os.AsyncTask$2.call(AsyncTask.java:185) 
04-15 21:38:55.589: W/AsyncTask(27597):  at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:305) 
04-15 21:38:55.589: W/AsyncTask(27597):  at java.util.concurrent.FutureTask.run(FutureTask.java:137) 
04-15 21:38:55.589: W/AsyncTask(27597):  at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1068) 
04-15 21:38:55.589: W/AsyncTask(27597):  at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:561) 
04-15 21:38:55.589: W/AsyncTask(27597):  at java.lang.Thread.run(Thread.java:1096) 
04-15 21:38:55.589: D/MyTask(27597): cancel() returned: true 
04-15 21:38:55.589: D/MyTask(27597): returning from doInBackground() 
04-15 21:38:55.659: D/MyTask(27597): onPostExecute() 
+1

Neden 'doInBackground' içinden bir' AsyncTask' iptal etmek isteyeyim? Bu mantıklı değil. "İptal (...)" yöntemi, kasıtlı olarak kodun çalışan iş parçacığı dışında (diğer bir deyişle UI iş parçacığı) yürütmeyi durdurmasına izin vermesi anlamına gelir. Eğer 'doInBackground' içindeki kodun herhangi bir sebepten dolayı kendini sonlandırması gerekiyorsa, o zaman basitçe 'geri dönmelidir. Eğer 'onPostExecute (...)' işlevinin bir yalancı-iptalin sonucu olarak belirli eylemleri gerçekleştirmesini istemiyorsanız, 'false' döndürün, aksi takdirde 'true' değerini döndürün – Squonk

+0

@MisterSquonk, "İptal (...) yöntemi" kasıtlı olarak, çalışan iş parçacığının dışındaki kodun yürütmeyi durdurmasına izin vermesi gerekiyordu. " Belgeler, yalnızca UI iş parçacığından çağrıldığını söylemez. Nedeni olmayan geçici çözümler kullanmak yerine, neden 'onCancelled() 'ın varolan kodunu yeniden kullanmıyoruz? –

+1

Anlaşmaya göre, belgeler yalnızca UI iş parçacığından çağrılması gerektiğini söylemez, ancak bu en mantıklı görünür. Bunun nedeni, belgelerin "doInBackground" unun kendi çalışmasını durdurup durdurmayacağını (iptal etme çağrısının bir sonucu olarak) görmek için isCancelled() işlevini düzenli olarak denetlemesi gerektiğini söylüyor. Eğer 'doInBackground' işlevi 'cancel' ise normal ise o zaman 'isCancelled() 'nin anlamı ne olurdu? – Squonk

cevap

3
  1. - ancak bu durumda, böylece,) (doInBackground içinden (doğru) iptal aradığınız iş parçacığının kendiliğinden bir kesinti göndermesine neden olur.

  2. Kodunuz Android 2 çalışıyorsa ancak Android 4. Sorun Dokümanları alıntı) (iptal üzerinde davranış Android 2 ve Android 4. arasına

    Android 2.3.7 onPostExecute değişti olmasıdır:

    DOIBackground sonra UI iş parçacığı üzerinde çalışır. Belirtilen sonuç doInBackground tarafından döndürülen değer veya görev iptal edildiğinde veya bir istisna oluştuğunda geçersizdir.

    Android 4.0.1 onPostExecute: doInBackground sonra UI iş parçacığı üzerinde

    çalıştırır. Belirtilen sonuç, doInBackground tarafından döndürülen değer . Bu yöntem, görevi iptal edildiyse çağrılmaz.

1

Sen boş dönmek ve OnPostExecute içinde dönüşünü davranmalı. doInBackground() çalışan iş parçacığı için bir kesme gönderir (true) iptal diyoruz çünkü bir istisna vardır