2011-06-20 30 views
3

首先,請不要tl; dr這個。它只是很多可快速掃描的代碼。實際的句子很少,簡潔:)。爲什麼我在AsyncTask中獲取此ClassCastException?

我有一個奇怪的問題。 A ClassCastException正在強制關閉我的Activity,但該例外並不表明問題實際存在於何處。這裏的例外:

E/AndroidRuntime( 402): FATAL EXCEPTION: AsyncTask #4 
E/AndroidRuntime( 402): java.lang.RuntimeException: An error occured while executing doInBackground() 
E/AndroidRuntime( 402): at android.os.AsyncTask$3.done(AsyncTask.java:200) 
E/AndroidRuntime( 402): at java.util.concurrent.FutureTask$Sync.innerSetException(FutureTask.java:274) 
E/AndroidRuntime( 402): at java.util.concurrent.FutureTask.setException(FutureTask.java:125) 
E/AndroidRuntime( 402): at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:308) 
E/AndroidRuntime( 402): at java.util.concurrent.FutureTask.run(FutureTask.java:138) 
E/AndroidRuntime( 402): at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1088) 
E/AndroidRuntime( 402): at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:581) 
E/AndroidRuntime( 402): at java.lang.Thread.run(Thread.java:1019) 
E/AndroidRuntime( 402): Caused by: java.lang.ClassCastException: [Ljava.lang.Object; 
E/AndroidRuntime( 402): at mypackage.DayActivity$EventsFetcher.doInBackground(DayActivity.java:1) 
E/AndroidRuntime( 402): at android.os.AsyncTask$2.call(AsyncTask.java:185) 
E/AndroidRuntime( 402): at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:306) 
E/AndroidRuntime( 402): ... 4 more 
W/ActivityManager( 61): Force finishing activity mypackage/mypackage.DayActivity 

正如你所看到的,它說,對DayActivity.java 1號線發生錯誤,這是默認的包聲明(即package mypackage)。我的doInBackground方法。在這裏,古怪的加劇,作爲整個方法基本上是try/catch塊:

@Override 
protected List<Event> doInBackground(Void... params) { 
    try { 
     final List<Event> events; 
     if (connectivityReceiver.hasConnection()) { 
      events = WebApi.getEvents(Util.getSelectedUser(DayActivity.this).getId(), start, end); 
     } 
     else if (Util.isPeriodCached(DayActivity.this, start, end)) { 
      final List<Event> allEvents = (List<Event>) new Cache(DayActivity.this).get(Cache.EVENTS); 
      events = Util.filterEvents(allEvents, start, end, Util.getSelectedUser(DayActivity.this).getId()); 
     } 
     else { 
      events = null; 
     } 
     return events; 
    } 
    catch (Exception e) { 
     Log.e(Const.TAG, "Could not fetch events for day view", e); 
    } 
    return null; 
} 

從理論上講,應該拋出被捕獲並記錄任何異常。我不明白這是怎麼發生的。訣竅是,在onPostExecute,運行此代碼:

if (!connectivityReceiver.hasConnection()) { 
    Util.retryDialog(DayActivity.this, R.string.no_cache, R.string.no_cache_msg, 
     new EventsFetcher(dialog), false).show(); 
} 

這裏的retryDialog()

public static Dialog retryDialog(final Activity context, int titleRes, int messageRes, 
     final AsyncTask retry, final boolean finishOnCancel) { 
    return new AlertDialog.Builder(context) 
     .setTitle(titleRes) 
     .setMessage(messageRes) 
     .setPositiveButton(R.string.retry, new DialogInterface.OnClickListener() { 
      @Override 
      public void onClick(DialogInterface dialog, int which) { 
       if (retry != null) { 
        retry.execute(); 
       } 
      } 
     }) 
     .setNegativeButton(R.string.cancel, new DialogInterface.OnClickListener() { 
      @Override 
      public void onClick(DialogInterface dialog, int which) { 
       if (finishOnCancel) { 
        context.finish(); 
       } 
      } 
     }) 
     .create(); 
} 

的問題是,該任務只能用一次,被顯示的對話框,但是當我點擊重試拋出異常,崩潰我的應用程序。

回答

3

什麼AsyncTask你通過重試? AsyncTask只能執行一次,因此您需要創建一個新實例,而不是嘗試重新啓動已執行的實例。從javadoc for AsyncTask摘自:

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

編輯:..這是我如何解釋堆棧跟蹤。在AsyncTask中執行完成時出現錯誤。這是錯誤的是一個Object[]的東西,它不是。可能從doInBackgroundonPostExecute,但這只是一個瘋狂的猜測。如果這是你正在嘗試做的事情,可能是由於任務重新啓動造成的。

+2

我'EventsFetcher'被延長'的AsyncTask <太虛,太虛,列表>'確實也嘗試投放'doInBackground'的結果'Object',或類似的東西的時候被扔那個例外。我只是將'retryDialog'的第四個參數更改爲'AsyncTask >'並且它工作正常。 – Felix

+0

很好,它解決了你的問題! – Kaj

+0

謝謝,它也幫助解決了我的問題。我宣佈了一個新的AsyncTask (),並且由於未知原因,我得到了與OP相同的異常。當我將其更改爲AsyncTask ()時,只是從doInBackground()返回「」,錯誤消失了。 – user462982

0
if (!connectivityReceiver.hasConnection()) { 
Util.retryDialog(DayActivity.this, R.string.no_cache, R.string.no_cache_msg, 
    new EventsFetcher(dialog), false).show(); 

}

這裏是看new EventsFetcher(dialog)被映射到final AsyncTask retry這是什麼原因?

public static Dialog retryDialog(final Activity context, int titleRes, int messageRes, 
    final AsyncTask retry, final boolean finishOnCancel) { 
+0

'EventsFetcher'類擴展了'AsyncTask '。它是包含發佈的'doInBackground'和'onPostExecute'部分的同一個類。它基本上是一個重試**本身**的'AsyncTask'。 – Felix

+0

@Felix您是否看到我的帖子?你不能執行一次'AsyncTask'兩次 – Kaj

+0

@Kaj是的,這就是爲什麼它會創建一個'EventsFetcher'的新實例(我傳遞'new EventsFetcher(dialog)')。 – Felix

相關問題