[英]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 : 取自AsadTask的javadoc :
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.