2013-12-08 9 views
26

Ich bekomme diesen Fehler innerhalb einer erweiterten asynctask, aber ich bin mir wirklich sicher, dass Objekt [] ist ein Void [].Objekt [] kann nicht in Void [] in AsyncTask umgewandelt werden

Das ist meine Gewohnheit AsyncTask ist:

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); 
} 

Und das ist die SubClass, die das Problem verursacht:

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>()); 
    } 
} 

Schließlich ist dies der Fehler:

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) 

ich kann erkläre diese Ausnahme nicht, weil ich Void als Parameter angegeben habe! Das sollte kein Objekt sein. Haben Sie Lösungen?

bearbeiten: ListPalinasAsyncTask.java:19 bezieht sich auf:

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

RepeatableAsyncTask.java:43:

result = repeatInBackground(inputs); 

EDIT 2:

Ich bin Aufruf Führen Sie diesen Weg aus:

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

Antwort

33

Lösung gefunden:

das Problem war:

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

Ich verwende generic AsyncTask zu Aufruf des Execut e, diese Klasse würde Void als Parameter übergeben und niemals .execute() auf ListPalinasAsynkTask aufrufen, stattdessen wird sie ListPlinasAsynkTask.execute (Void) aufrufen. Das gibt den Fehler.

Lösungen:

  1. Verwenden ListPalinasAsynkTask statt Generika AsyncTask
  2. Besser ein: eine neue Klasse VoidRepeatableAsyncTask erstellen und andere Void AsyncTasks, dass man verlängern machen.

So:

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

Dann so etwas wie dies Sie leicht ausführen aufrufen können:

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

Dies ruft die No-Parameter Execute-Methode von AsyncTask.

+0

Perfekte Lösung. Der Methodenaufruf 'super.execute()' ist hier der wichtige Teil. – Mulgard

+1

Ihre Erklärung ist nicht korrekt. Korrekt ist hier http://StackOverflow.com/A/34400140/5455629 – q126y

+0

das gleiche gilt für super.executeOnExecutor (...) - stellen Sie sicher, "Super" in den Anruf einzuschließen, wenn Sie AsyncTask –

0

Versuchen Sie es mit:

result = repeatInBackground((Void) inputs); 

statt

result = repeatInBackground(inputs); 
+0

diese Weise kann ich einen nicht-Void geben als Eingabe –

+2

@LucaVitucci Sie für einen Void fragen als Parameter nicht in der Lage sein ... Du sollte um nur Void als Eingabe zu geben –

+0

Sie schlagen vor, RepeatableAsyncTask zu bearbeiten, das eine generische Klasse ist, ich frage nicht nach Void als Parameter, ich frage nach generischem Parameter A. Ich plane, diese Klasse für Nicht-Klassen zu verwenden. Void auch. –

17

Eine andere Möglichkeit, mit der ich es gelöst habe, ist Object in Parametern zu übergeben, auch wenn Sie die Parameter nicht verwenden.

new AsyncTask<Object, Void, MergeAdapter>() 

und die Überschreibung:

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

Das gilt vor (in meinem Fall), wenn Sie verschiedene Arten von AsyncTasks ein Verfahren übergeben wollen und natürlich Sie kümmern sich nicht um die Parameter.

7

Die Lösung ist viel einfacher, wie ich es sehe. einfach das Unterklasse-Objekt auf diese Weise erstellen:

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

Angabe des Generics Type als void für die AsyncTask, anstatt es zu belassen (oder in meinem Fall als Wildcards ) löste es für mich. – JCricket

+0

Sie haben eine Engelklammer vergessen – winklerrr

Verwandte Themen