繁体   English   中英

为什么我在AsyncTask中得到这个ClassCastException?

[英]Why am I getting this ClassCastException in my AsyncTask?

首先,请不要这样做。 它只是很多可快速扫描的代码。 实际的句子很少而且简洁:)。

我有一个奇怪的问题。 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

如您所见,它表示错误发生在DayActivity.java第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();
}

问题是该任务有效,对话框会显示,但是当我点击重试时会抛出异常,导致我的应用程序崩溃。

你传入AsyncTask重试的是什么? AsyncTask只能执行一次,因此您需要创建一个新实例,而不是尝试重新启动已执行的实例。 取自AsadTaskjavadoc

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

编辑:..这就是我如何解释堆栈跟踪。 在AsyncTask中执行完成后出现问题。 错误的是将Object[]转换为不是它的东西。 可能是从doInBackground转到onPostExecute ,但这只是一个疯狂的猜测。 如果您正在尝试这样做,可能会由重新启动任务引起。

刚遇到同样的问题。 解决方案不是公认的答案,而是下面的felix评论:确保您的AsyncTask引用是类型安全的。 含义:使用AsyncTask<Your, Parameter, Types>而不仅仅是AsyncTask 后者似乎默认AsyncTask<Object, Object, Object> ,因此,从ClassCastException异常Object

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) {

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM