Почему я получаю это ClassCastException в моей AsyncTask? - PullRequest
4 голосов
/ 20 июня 2011

Прежде всего, пожалуйста, не делайте этого. Это просто много быстро сканируемого кода. Реальных предложений мало и лаконично:).

У меня странная проблема. ClassCastException принудительно закрывает мой Activity, но исключение не указывает, где на самом деле проблема. Вот исключение:

E/AndroidRuntime(  402): FATAL EXCEPTION: AsyncTask #4
E/AndroidRuntime(  402): java.lang.RuntimeException: An error occured while executing doInBackground()
E/AndroidRuntime(  402):    at android.os.AsyncTask$3.done(AsyncTask.java:200)
E/AndroidRuntime(  402):    at java.util.concurrent.FutureTask$Sync.innerSetException(FutureTask.java:274)
E/AndroidRuntime(  402):    at java.util.concurrent.FutureTask.setException(FutureTask.java:125)
E/AndroidRuntime(  402):    at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:308)
E/AndroidRuntime(  402):    at java.util.concurrent.FutureTask.run(FutureTask.java:138)
E/AndroidRuntime(  402):    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1088)
E/AndroidRuntime(  402):    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:581)
E/AndroidRuntime(  402):    at java.lang.Thread.run(Thread.java:1019)
E/AndroidRuntime(  402): Caused by: java.lang.ClassCastException: [Ljava.lang.Object;
E/AndroidRuntime(  402):    at mypackage.DayActivity$EventsFetcher.doInBackground(DayActivity.java:1)
E/AndroidRuntime(  402):    at android.os.AsyncTask$2.call(AsyncTask.java:185)
E/AndroidRuntime(  402):    at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:306)
E/AndroidRuntime(  402):    ... 4 more
W/ActivityManager(   61):   Force finishing activity mypackage/mypackage.DayActivity

Как видите, в сообщении указывается, что ошибка возникает в строке 1 DayActivity.java, которая является объявлением пакета по умолчанию (т.е. package mypackage).

Вот мой doInBackground метод. Здесь странность усиливается, поскольку весь метод представляет собой try/catch блок:

@Override
protected List<Event> doInBackground(Void... params) {
    try {
        final List<Event> events;
        if (connectivityReceiver.hasConnection()) {
            events = WebApi.getEvents(Util.getSelectedUser(DayActivity.this).getId(), start, end);
        }
        else if (Util.isPeriodCached(DayActivity.this, start, end)) {
            final List<Event> allEvents = (List<Event>) new Cache(DayActivity.this).get(Cache.EVENTS);
            events = Util.filterEvents(allEvents, start, end, Util.getSelectedUser(DayActivity.this).getId());
        }
        else {
            events = null;
        }
        return events;
    }
    catch (Exception e) {
        Log.e(Const.TAG, "Could not fetch events for day view", e);
    }
    return null;
}

Теоретически, любое выброшенное исключение должно быть перехвачено и зарегистрировано. Я не понимаю, как это не могло произойти. Хитрость в том, что в onPostExecute я запускаю этот код:

if (!connectivityReceiver.hasConnection()) {
    Util.retryDialog(DayActivity.this, R.string.no_cache, R.string.no_cache_msg,
        new EventsFetcher(dialog), false).show();
}

Вот retryDialog():

public static Dialog retryDialog(final Activity context, int titleRes, int messageRes,
        final AsyncTask retry, final boolean finishOnCancel) {
    return new AlertDialog.Builder(context)
        .setTitle(titleRes)
        .setMessage(messageRes)
        .setPositiveButton(R.string.retry, new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                if (retry != null) {
                    retry.execute();
                }
            }
        })
        .setNegativeButton(R.string.cancel, new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                if (finishOnCancel) {
                    context.finish();
                }
            }
        })
        .create();
}

Проблема в том, что задача работает один раз, отображается диалоговое окно, но затем, когда я нажимаю кнопку «Повторить», возникает исключение, что приводит к сбою приложения.

Ответы [ 3 ]

3 голосов
/ 20 июня 2011

Что AsyncTask вы передаете, чтобы повторить попытку?AsyncTask может выполняться только один раз, поэтому вам нужно создать новый экземпляр, а не пытаться перезапустить уже выполненный экземпляр.Взято из javadoc для AsyncTask :

The task can be executed only once (an exception will be thrown if a second execution is attempted.)

Редактировать: .. так я интерпретирую трассировку стекаЧто-то идет не так при выполнении сделано в AsyncTask.То, что неправильно, это приведение Object[] к чему-то, что это не так.Возможно, при переходе от doInBackground к onPostExecute, но это только дикое предположение.Это может быть вызвано перезапуском задачи, если вы пытаетесь это сделать.

0 голосов
/ 19 апреля 2018

Просто была такая же проблема.Решение - это не принятый ответ, а комментарий Феликса под ним: убедитесь, что ваша ссылка AsyncTask безопасна для типов.Значение: используйте AsyncTask<Your, Parameter, Types> вместо просто AsyncTask.По-видимому, по умолчанию используется значение AsyncTask<Object, Object, Object>, и, следовательно, ClassCastException от Object

0 голосов
/ 20 июня 2011
if (!connectivityReceiver.hasConnection()) {
Util.retryDialog(DayActivity.this, R.string.no_cache, R.string.no_cache_msg,
    new EventsFetcher(dialog), false).show();

}

Вот видите, new EventsFetcher(dialog) сопоставлен с final AsyncTask retry это причина?

public static Dialog retryDialog(final Activity context, int titleRes, int messageRes,
    final AsyncTask retry, final boolean finishOnCancel) {
...