web-dev-qa-db-fra.com

L'objet [] ne peut pas être converti en annulation [] dans AsyncTask

Je reçois cette erreur à l'intérieur d'un asyncte étendu, mais je suis vraiment sûr que Object [] IS est vide [].

Ceci est ma tâche Async personnalisée:

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

Et c'est la sous-classe qui donne le problème:

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

Enfin, c'est l'erreur:

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)

Je ne peux pas expliquer cette exception car je donne Void en tant que paramètre! Cela ne devrait pas être un objet ... Avez-vous des solutions?

Éditer : ListPalinasAsyncTask.Java:19 fait référence à:

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

RepeatableAsyncTask.Java:43:

result = repeatInBackground(inputs);

EDIT 2:

J'appelle exécuter de cette façon:

AsyncTask mAsyncTask = new ListPalinasAsynkTask(callback);
....
mAsyncTask.execute();
28
Luca Vitucci

Solution trouvée:

le problème était le suivant:

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

J'utilise AsyncTask générique pour appeler execute, cette classe passera Void en tant que paramètre et n'appellera jamais .execute () sur ListPalinasAsynkTask; Cela donne l'erreur.

Solutions:

  1. Utilisez ListPalinasAsynkTask au lieu de AsyncTask générique
  2. Meilleure: créez une nouvelle classe VoidRepeatableAsyncTask et faites en sorte que d'autres Void AsyncTasks l'étendent.

Comme ça:

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

Ensuite, vous pouvez facilement utiliser quelque chose comme ceci pour appeler execute:

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

Cela appellera la méthode d'exécution sans paramètres d'AsyncTask.

37
Luca Vitucci

Une solution alternative que j'ai résolue consiste à passer Object dans les paramètres, même si vous n'utilisez pas les paramètres.

new AsyncTask<Object, Void, MergeAdapter>()

et la dérogation:

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

Ce qui précède s’applique (dans mon cas) si vous souhaitez transmettre différents types d’AsyncTasks à une méthode et, bien entendu, vous ne vous souciez pas des paramètres.

18
Diolor

La solution est beaucoup plus simple à mon sens . Créez simplement l'objet de sous-classe de la manière suivante:

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

Essayez d'utiliser:

result = repeatInBackground((Void) inputs);

au lieu de 

result = repeatInBackground(inputs);
0
Raghav Sood