web-dev-qa-db-ja.com

Object []はAsyncTaskでVoid []にキャストできません

拡張asynctask内でこのエラーが発生していますが、Object [] IS a 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();
29
Luca Vitucci

解決策が見つかりました:

問題はこれでした:

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

私は汎用のAsyncTaskを使用して実行を呼び出していますが、そのクラスはVoidをパラメーターとして渡し、ListPalinasAsynkTaskで.execute()を呼び出さず、代わりにListPalinasAsynkTask.execute(Void)を呼び出します。エラーが発生します。

ソリューション:

  1. 一般的なAsyncTaskの代わりにListPalinasAsynkTaskを使用する
  2. より良いもの:新しいクラスVoidRepeatableAsyncTaskを作成し、他のVoid 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のno-parameters executeメソッドが呼び出されます。

39
Luca Vitucci

私が解決した別の方法は、パラメーターを使用しない場合でも、パラメーターにObjectを渡すことです。

new AsyncTask<Object, Void, MergeAdapter>()

そしてオーバーライド:

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

上記は(私の場合)異なるタイプのAsyncTasksをメソッドに渡したいが、もちろんパラメータを気にしない場合に当てはまります。

19
Diolor

私が見る限り、解決策ははるかに単純です。この方法でサブクラスオブジェクトを作成するだけです。

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

この問題が発生している場合は、派生クラスオブジェクトを作成し、その基本クラス変数(AsyncTask)を追加した可能性があります。したがって、このエラーが発生しています。
AsyncTask mAsyncTask = new ListPalinasAsynkTask(callback);

Lintは、この「実行するためのチェックされていない呼び出し。パラメータ...」のような場合にも警告を出します。

ソリューションはListPalinasAsynkTask mAsyncTask = new ListPalinasAsynkTask(callback);です。次に、executeを呼び出します。それはうまくいきます

0
Amit

使ってみてください:

result = repeatInBackground((Void) inputs);

の代わりに

result = repeatInBackground(inputs);
0
Raghav Sood