2013-12-08 19 views
26

我在擴展的asynctask中出現此錯誤,但我確定Object []是一個Void []。在AsyncTask中無法將對象[]轉換爲Void []

這是我的自定義的AsyncTask:

public abstract class RepeatableAsyncTask<A, B, C> extends AsyncTask<A, B, C> { 
private static final String TAG = "RepeatableAsyncTask"; 
public static final int DEFAULT_MAX_RETRY = 5; 

private int mMaxRetries = DEFAULT_MAX_RETRY; 
private Exception mException = null; 

/** 
* Default constructor 
*/ 
public RepeatableAsyncTask() { 
    super(); 
} 

/** 
* Constructs an AsyncTask that will repeate itself for max Retries 
* @param retries Max Retries. 
*/ 
public RepeatableAsyncTask(int retries) { 
    super(); 
    mMaxRetries = retries; 
} 

/** 
* Will be repeated for max retries while the result is null or an exception is thrown. 
* @param inputs Same as AsyncTask's 
* @return Same as AsyncTask's 
*/ 
protected abstract C repeatInBackground(A...inputs); 

@Override 
protected final C doInBackground(A...inputs) { 
    int tries = 0; 
    C result = null; 

    /* This is the main loop, repeatInBackground will be repeated until result will not be null */ 
    while(tries++ < mMaxRetries && result == null) { 
     try { 
      result = repeatInBackground(inputs); 
     } catch (Exception exception) { 
      /* You might want to log the exception everytime, do it here. */ 
      mException = exception; 
     } 
    } 
    return result; 
} 

/** 
* Like onPostExecute but will return an eventual Exception 
* @param c Result same as AsyncTask 
* @param exception Exception thrown in the loop, even if the result is not null. 
*/ 
protected abstract void onPostExecute(C c, Exception exception); 

@Override 
protected final void onPostExecute(C c) { 
    super.onPostExecute(c); 
    onPostExecute(c, mException); 
} 

這是給人的問題子類:

public class ListPalinasAsynkTask extends RepeatableAsyncTask<Void, Void, List<Palina>>{ 
    private static final String TAG = "ListPalinasAsynkTask"; 
    private static final boolean D = SystemConstants.ACTIVE_DEBUG; 

    private ApiRequest.ListPalinasCallback mCallback; 

    public ListPalinasAsynkTask(ApiRequest.ListPalinasCallback callback) { 
     if(D) Log.d(TAG, "Called: ListPalinasAsynkTask([callback])"); 
     mCallback = callback; 
    } 

    @Override 
    protected List<Palina> repeatInBackground(Void... voids) { 
     /* Here i send request to get palinas */ 
     return Api.getPalinasNearMe(); 
    } 

    @Override 
    protected void onPostExecute(List<Palina> palinas, Exception exception) { 
     if(exception != null) 
      Logging.e(TAG, "Received exception in Asynk Task", exception); 
     if(palinas != null) 
      mCallback.result(palinas); 
     else 
      mCallback.result(new ArrayList<Palina>()); 
    } 
} 

最後,這是錯誤:

E/ListPalinasAsynkTask﹕ Received exception in Asynk Task 
    java.lang.ClassCastException: java.lang.Object[] cannot be cast to java.lang.Void[] 
      at ListPalinasAsynkTask.repeatInBackground(ListPalinasAsynkTask.java:19) 
      at RepeatableAsyncTask.doInBackground(RepeatableAsyncTask.java:43) 
      at android.os.AsyncTask$2.call(AsyncTask.java:288) 

我可以解釋這個例外,因爲我給Void作爲參數!這不應該是一個對象。 你有解決方案嗎?

編輯: ListPalinasAsyncTask.java:19是指:

public class ListPalinasAsynkTask extends RepeatableAsyncTask<Void, Void, List<Palina>> { 

RepeatableAsyncTask.java:43:

result = repeatInBackground(inputs); 

編輯2:

我打電話以這種方式執行:

AsyncTask mAsyncTask = new ListPalinasAsynkTask(callback); 
.... 
mAsyncTask.execute(); 

回答

33

發現的解決方案:

的問題是這樣的:

AsyncTask mAsyncTask = new ListPalinasAsynkTask(callback); 
.... 
mAsyncTask.execute(); 

我使用的是通用的AsyncTask來致電執行e,該類將傳遞Void作爲參數,並且不會調用ListPalinasAsynkTask上的.execute(),而是調用ListPalinasAsynkTask.execute(Void)。這給出了錯誤。

解決方案:

  1. 使用ListPalinasAsynkTask,而不是通用的AsyncTask
  2. 寧可一:創建一個新的類VoidRepeatableAsyncTask,使另一空隙AsyncTasks延長的那一個。

像這樣:

public abstract class VoidRepeatableAsyncTask<T> extends RepeatableAsyncTask<Void, Void, T> { 
    public void execute() { 
     super.execute(); 
    } 
} 

然後你就可以很容易地使用這樣的調用execute:

VoidRepeatableAsyncTask mAsyncTask = new ListPalinasAsynkTask(callback); 
.... 
mAsyncTask.execute(); 

這將調用無參數執行的AsyncTask的方法。

+0

完美的解決方案。方法調用'super.execute()'是這裏的重要部分。 – Mulgard

+1

你的解釋不正確。正確的一個在這裏http://stackoverflow.com/a/34400140/5455629 – q126y

+0

同樣適用於super.executeOnExecutor(...) - 如果您重寫AsyncTask –

0

嘗試使用:

result = repeatInBackground((Void) inputs); 

代替

result = repeatInBackground(inputs); 
+0

這樣,我就無法@LucaVitucci你問一個虛空作爲參數給一個非空輸入 –

+2

...你應該只給出Void作爲輸入 –

+0

你建議編輯是一個泛型類的RepeatableAsyncTask,我沒有要求作爲參數的Void,我要求的泛型參數A.我打算使用這個類的非 - 無效也。 –

17

我解決它的另一種方法是在參數中傳遞Object,即使您不使用參數。

new AsyncTask<Object, Void, MergeAdapter>() 

和覆蓋:

@Override 
protected ReturnClass doInBackground(Object... params) { 
    //... 
} 

上述適用(在我的情況),如果你想通過不同類型的AsyncTasks的一種方法,當然你不關心的參數。

7

解決方案非常簡單,因爲我看到它。 以這種方式只需要創建一個子類對象:

AsyncTask<Void, Void, List<Palina> mAsyncTask = new ListPalinasAsynkTask(callback); 
.... 
mAsyncTask.execute(); 
+0

爲AsyncTask指定類型爲void,而不是將其關閉(或在我的情況下作爲通配符)爲我解決它。 – JCricket

+0

你忘了天使支架 – winklerrr

相關問題