【问题标题】:Object[] cannot be cast to Void[] in AsyncTaskObject[] 不能在 AsyncTask 中强制转换为 Void[]
【发布时间】:2013-12-25 16:16:32
【问题描述】:

我在扩展的 asynctask 中遇到了这个错误,但我确定 Object[] 是一个 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();

【问题讨论】:

    标签: java android void


    【解决方案1】:

    如果出现这个问题,那么您可能已经创建了一个派生类对象并添加了它的基类变量 (AsyncTask)。所以这个错误正在发生。
    AsyncTask mAsyncTask = new ListPalinasAsynkTask(callback);

    当您这样做时,Lint 也会发出警告“未经检查的执行调用。参数 ....”

    解决办法是 ListPalinasAsynkTask mAsyncTask = new ListPalinasAsynkTask(callback); 然后调用它执行。它会正常工作

    【讨论】:

      【解决方案2】:

      在我看来,解决方案要简单得多。 只需这样创建子类对象:

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

      【讨论】:

      • 将泛型类型指定为 AsyncTask 的 void 而不是将其关闭(或者在我的情况下作为通配符 ,?,?>)为我解决了这个问题。
      • 你忘了一个天使括号
      【解决方案3】:

      我解决它的另一种方法是在参数中传递Object,即使您不使用参数。

      new AsyncTask<Object, Void, MergeAdapter>()
      

      和覆盖:

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

      如果您想将不同类型的 AsyncTasks 传递给方法并且当然您不关心参数,则上述适用(在我的情况下)。

      【讨论】:

      • 哇。这为我解决了它。但我仍然不明白为什么 Void 作为第一个类型参数会给出“java.lang.ClassCastException: java.lang.Object[] cannot be cast to java.lang.Void[]”错误。
      【解决方案4】:

      找到解决方案:

      问题是这样的:

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

      我使用通用 AsyncTask 调用执行,该类将 Void 作为参数传递,并且永远不会在 ListPalinasAsynkTask 上调用 .execute(),而是调用 ListPalinasAsynkTask.execute(Void)。这给出了错误。

      解决方案:

      1. 使用 ListPalinasAsynkTask 代替通用 AsyncTask
      2. 更好的方法:创建一个新类 VoidRepeatableAsyncTask 并使其他 Void AsyncTask 扩展该类。

      像这样:

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

      然后你可以很容易地使用这样的东西来调用执行:

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

      这将调用AsyncTask的无参数执行方法。

      【讨论】:

      • 完美解决方案。方法调用super.execute()是这里的重要部分。
      • 您的解释不正确。正确的在这里stackoverflow.com/a/34400140/5455629
      • 这同样适用于 super.executeOnExecutor(...) - 如果您要覆盖 AsyncTask,请确保在调用中包含“super”
      • 这个解决方案可能更简单!像这样声明它:AsyncTask&lt;Void, Void, List&lt;Palina&gt;&gt; asyncTask
      【解决方案5】:

      尝试使用:

      result = repeatInBackground((Void) inputs);
      

      而不是

      result = repeatInBackground(inputs);
      

      【讨论】:

      • 这样我就不能提供一个非 Void 作为输入
      • @LucaVitucci 你要求一个 Void 作为参数......你应该只给 Void 作为输入
      • 您建议编辑作为泛型类的 RepeatableAsyncTask,我不是要求 Void 作为参数,而是要求泛型参数 A。我打算将此类用于非- 也无效。
      猜你喜欢
      • 2021-06-25
      • 1970-01-01
      • 2011-06-17
      • 2012-04-12
      • 1970-01-01
      • 1970-01-01
      • 2016-05-01
      • 2015-05-24
      • 1970-01-01
      相关资源
      最近更新 更多