简体   繁体   English

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

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

First off, please do not tl;dr this. 首先,请不要这样做。 It just a lot of quickly-scannable code. 它只是很多可快速扫描的代码。 Actual sentences are few and concise :). 实际的句子很少而且简洁:)。

I have a weird problem. 我有一个奇怪的问题。 A ClassCastException is force-closing my Activity , but the exception does not indicate where the problem actually is. ClassCastException强制关闭我的Activity ,但异常并不表示问题的实际位置。 Here's the exception: 这是例外:

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

As you can see, it says that the error occurs on line 1 of DayActivity.java , which is the default package declaration (ie package mypackage ). 如您所见,它表示错误发生在DayActivity.java第1 DayActivity.java ,这是默认的包声明(即package mypackage )。

Here's my doInBackground method. 这是我的doInBackground方法。 Here, the weirdness intensifies, as the whole method is basically a try/catch block: 在这里,奇怪的问题愈演愈烈,因为整个方法基本上都是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;
}

In theory, any exception thrown should be caught and logged. 理论上,应该捕获并记录任何抛出的异常。 I don't see how that could not happen. 我不明白这是怎么回事。 The trick is that in onPostExecute , I run this code: 诀窍是在onPostExecute ,我运行以下代码:

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

Here's retryDialog() : 这是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();
}

The problem is that the task works once, the dialog gets displayed, but then when I click retry that exception is thrown, crashing my app. 问题是该任务有效,对话框会显示,但是当我点击重试时会抛出异常,导致我的应用程序崩溃。

What AsyncTask are you passing in to retry? 你传入AsyncTask重试的是什么? an AsyncTask can only execute once, so you need to create a new instance, and not try to restart the already executed instance. AsyncTask只能执行一次,因此您需要创建一个新实例,而不是尝试重新启动已执行的实例。 Taken from the javadoc for AsyncTask : 取自AsadTaskjavadoc

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

Edit: .. this is how I interpret the stacktrace. 编辑:..这就是我如何解释堆栈跟踪。 Something is going wrong when executing done in AsyncTask. 在AsyncTask中执行完成后出现问题。 The thing that is wrong is a cast of Object[] to something that it isn't. 错误的是将Object[]转换为不是它的东西。 Possibly when going from doInBackground to onPostExecute , but that's just a wild guess. 可能是从doInBackground转到onPostExecute ,但这只是一个疯狂的猜测。 Might be caused by a restart of the task, if that is what you are trying to do. 如果您正在尝试这样做,可能会由重新启动任务引起。

Just had the same problem. 刚遇到同样的问题。 The Solution is not the accepted answer but rather felix comment below it: Make sure your AsyncTask reference is typesafe. 解决方案不是公认的答案,而是下面的felix评论:确保您的AsyncTask引用是类型安全的。 Meaning: use AsyncTask<Your, Parameter, Types> instead of just AsyncTask . 含义:使用AsyncTask<Your, Parameter, Types>而不仅仅是AsyncTask Latter seems to default to AsyncTask<Object, Object, Object> and therefore the ClassCastException from Object 后者似乎默认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();

} }

Here is see new EventsFetcher(dialog) is mapped to final AsyncTask retry is this the cause? 这里看到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.

相关问题 为什么我得到这个ClassCastException? - Why am I getting this ClassCastException? 为什么我在简单的Java程序中得到ClassCastException? - why am i getting ClassCastException in my simple java program? 为什么我在这种情况下得到ClassCastException - why i am getting ClassCastException in this case 为什么我在这里得到ClassCastException? - Why am I getting a ClassCastException here? 为什么我在 Jenkins 构建中收到 ClassCastException - Why am I getting ClassCastException in Jenkins build 为什么会收到此ClassCastException? 在eclipse上工作,但不是在智能上工作 - Why am I getting this ClassCastException? Working on eclipse, but not in intelliJ 为什么我在尝试反序列化列表时收到 ClassCastException - Why am I getting ClassCastException when trying to deserialize a list 为什么在生成 javadoc 时会收到 ClassCastException? - Why am I getting a ClassCastException when generating javadocs? 反序列化包含树形图的对象时,为什么会收到ClassCastException? - Why am I getting a ClassCastException when deserializing an object that contains a treemap? 为什么我会收到此错误?? java.lang.ClasscastException - Why am I getting this error ?? java.lang.ClasscastException
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM