Fixed
Status Update
Comments
ro...@android.com <ro...@android.com> #2
You don't need to initialize and execute AsyncTask in onCreate to load it, you only need to "touch" the class. For instance Class.forName() is enough.
pe...@gmail.com <pe...@gmail.com> #3
I verified calling
Class.forName("android.os.AsyncTask");
is enough.
Class.forName("android.os.AsyncTask");
is enough.
na...@gmail.com <na...@gmail.com> #4
On Android 2.2 emulator, I have added the class touching code in onCreate of my main activity, but the error is still present. Basically I'm trying to monitor the call state of phone using a subclass of PhoneStateListener. Code goes below
try {
Class.forName("android.os.AsyncTask");
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
b = new BackEnder();
bei = new Intent(this, BackEnder.class);
bei.putExtra("CALLNUMBER", "5554");
bindService(bei, null, BIND_AUTO_CREATE);
startService(bei);
try {
Class.forName("android.os.AsyncTask");
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
b = new BackEnder();
bei = new Intent(this, BackEnder.class);
bei.putExtra("CALLNUMBER", "5554");
bindService(bei, null, BIND_AUTO_CREATE);
startService(bei);
pe...@gmail.com <pe...@gmail.com> #5
Add it to your application's onCreate. Your main activity may not even be running or may run too late.
ja...@gmail.com <ja...@gmail.com> #6
I found that the issue was from invoking asynctasks from services, and according to http://developer.android.com/reference/android/os/AsyncTask.html (Threading Rules):
"The task instance must be created on the UI thread."
"The task instance must be created on the UI thread."
do...@gmail.com <do...@gmail.com> #7
[Comment deleted]
do...@gmail.com <do...@gmail.com> #8
Do it like this:
public class YourApplication extends Application {
@Override
public void onCreate() {
// workaround forhttp://code.google.com/p/android/issues/detail?id=20915
try {
Class.forName("android.os.AsyncTask");
} catch (ClassNotFoundException e) {
}
super.onCreate();
}
}
and define YourApplication in your Manifest.
public class YourApplication extends Application {
@Override
public void onCreate() {
// workaround for
try {
Class.forName("android.os.AsyncTask");
} catch (ClassNotFoundException e) {
}
super.onCreate();
}
}
and define YourApplication in your Manifest.
bd...@google.com <bd...@google.com>
[Deleted User] <[Deleted User]> #9
This issue struck me when trying to mock out AsyncTask in an instrumentation tests. Since instrumentation tests are run on a separate thread, creating mock objects of AsyncTask there will result in very strange behavior, where sometimes the handler messages get dropped.
ro...@android.com <ro...@android.com>
ma...@gmail.com <ma...@gmail.com> #10
I'm using 2.3.6 and encountered a somewhat similar issue when launching an activity so that my IntentService thread first broadcasts an intent that my broadcast receiver (running on main thread) catches and then starts the activity. In this activity, I use an AsyncTask defined as a non-static member variable:
private AsyncTask<Void, Void, Bitmap> mDownloadTask;
for downloading a bitmap from internet prior to displaying the UI (setting content view etc), which I then carry out in onPostExecute. I double checked with debugger, that the AsyncTask is instantiated in the main thread, but its onPostExecute strangely appears to be executing in my IntentService's thread which later causes me an android.view.ViewRoot$CalledFromWrongThreadException when accessing the views from main thread. I had to wrap my onPostExecute code inside a Runnable and explicitly tell it to be run on UI thread to make the problem go away.
private AsyncTask<Void, Void, Bitmap> mDownloadTask;
for downloading a bitmap from internet prior to displaying the UI (setting content view etc), which I then carry out in onPostExecute. I double checked with debugger, that the AsyncTask is instantiated in the main thread, but its onPostExecute strangely appears to be executing in my IntentService's thread which later causes me an android.view.ViewRoot$CalledFromWrongThreadException when accessing the views from main thread. I had to wrap my onPostExecute code inside a Runnable and explicitly tell it to be run on UI thread to make the problem go away.
mi...@gmail.com <mi...@gmail.com> #11
On Android 2.3.4 onPostExecute was not called, when AsyncTask was started from IntentService. Class.forName("android.os.AsyncTask"); seems to work.
pa...@gmail.com <pa...@gmail.com> #12
People, please stop using AsyncTasks in threads another than main thread (IntentService for example). This cause your problems and pre-loading class is only workaround that might cause another problems.. For example at some point of time AsyncTask class may be unloaded and loaded again (on wrong thread).
ku...@gmail.com <ku...@gmail.com> #13
I am using Looper.prepare() and a new Handler inside my AysncTask.
Unfortunately, it is not solving my problem.
It is still showing "sending message to a dead thread" when I a calling it for the 3rd time.
1st time and 2nd time it is OK. Very strange.
Unfortunately, it is not solving my problem.
It is still showing "sending message to a dead thread" when I a calling it for the 3rd time.
1st time and 2nd time it is OK. Very strange.
pa...@gmail.com <pa...@gmail.com> #14
Do you run any AsyncTask in your application in a thread another than UI? Check all your AsyncTasks, mainly focus on the one, that you execute as a first one.
ku...@gmail.com <ku...@gmail.com> #15
Hi,
I am creatng the AsyncTask from UI thread.. some onClick() method.
So, a new AysncTask is created when ever user clicks on that button.
here is my Code snippet:
@Override
protected Integer doInBackground(Context... arg0) {
if(Looper.myLooper() == null) {
Log.d("#### My Looper thread null!");
Looper.prepare();
}
// Main Handler
mHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
case (1):
// do something
// Send Msg (2)
break;
case (2):
this.getLooper().quit();
break;
}
};
// Start the Message loop
mHandler.sendEmptyMessage(1);
// loop
mHandler.getLooper().loop();
return 1;
}
So, it is running fine for 2 times. From 3rd time, it is showing:
"sending message to a Handler on a dead thread"
!! Please help.
Also, if I am directly calling "Looper.prepare();", it is telling "only one looper can be created" - this also at 3rd execution.
I am creatng the AsyncTask from UI thread.. some onClick() method.
So, a new AysncTask is created when ever user clicks on that button.
here is my Code snippet:
@Override
protected Integer doInBackground(Context... arg0) {
if(Looper.myLooper() == null) {
Log.d("#### My Looper thread null!");
Looper.prepare();
}
// Main Handler
mHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
case (1):
// do something
// Send Msg (2)
break;
case (2):
this.getLooper().quit();
break;
}
};
// Start the Message loop
mHandler.sendEmptyMessage(1);
// loop
mHandler.getLooper().loop();
return 1;
}
So, it is running fine for 2 times. From 3rd time, it is showing:
"sending message to a Handler on a dead thread"
!! Please help.
Also, if I am directly calling "Looper.prepare();", it is telling "only one looper can be created" - this also at 3rd execution.
pa...@gmail.com <pa...@gmail.com> #16
Anyway, why do you create a Handler inside of AsyncTask? Couldn't you just execute some code inside doInBackground rather than creating a handler?
The problem is that you are creating a Looper in a AsyncTask thread. When your AsyncTask is finished, the Looper is also killed, so when the handler is handling a message it use already dead thread.
In my opinion you shouldn't use Handler and AsyncTask in that manner.
new AsyncTask<Void, Void, Integer>() {
@Override
protected Integer doInBackground(Void... arg) {
// do something & don't worry, AsyncTask will finish itself after execution. This method is executed in a separate thread created by the system.
return null;
}
@Override
protected void onPostExecute(Integer result) {
// Here you can do something on UI thread after AsyncTask execution.
}
}.execute();
The problem is that you are creating a Looper in a AsyncTask thread. When your AsyncTask is finished, the Looper is also killed, so when the handler is handling a message it use already dead thread.
In my opinion you shouldn't use Handler and AsyncTask in that manner.
new AsyncTask<Void, Void, Integer>() {
@Override
protected Integer doInBackground(Void... arg) {
// do something & don't worry, AsyncTask will finish itself after execution. This method is executed in a separate thread created by the system.
return null;
}
@Override
protected void onPostExecute(Integer result) {
// Here you can do something on UI thread after AsyncTask execution.
}
}.execute();
cr...@gmail.com <cr...@gmail.com> #17
Does anybody know if this issue was resolved? i have the same problem with the IntentService and only happens on a device with Android 4.0.4.
I added this code and solved the problem but I want to know on which version was this solved add it to the if statement.
if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.JELLY_BEAN) {
try {
Class.forName("android.os.AsyncTask");
} catch (ClassNotFoundException e) {
Log.e(LOG_TAG, "Class android.os.AsyncTask not found!!!");
e.printStackTrace();
}
}
Thanks
Carlos
I added this code and solved the problem but I want to know on which version was this solved add it to the if statement.
if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.JELLY_BEAN) {
try {
Class.forName("android.os.AsyncTask");
} catch (ClassNotFoundException e) {
Log.e(LOG_TAG, "Class android.os.AsyncTask not found!!!");
e.printStackTrace();
}
}
Thanks
Carlos
le...@gmail.com <le...@gmail.com> #18
According to the history above, it was released on Jun 23, 2013 so it would be JellyBean or Kitkat.
pi...@gmail.com <pi...@gmail.com> #19
No idea if this was fixed, but I just had this issue with an IntentService and GCM, just as described by OP, but on an HTC One m8 with Lollipop. Am I seeing the same issue or do I need to look for the issue elsewhere?
Can anyone confirm this has actually been fixed? I'm not using AsyncTask - I'm using an EventBus to post events to my app's Activities if any is alive and that part works fine except for when I'm trying to show a Toast for instance, then I'm getting the exception in LogCat. I receive the event from my EventBus though.
I haven't tried the "touching"-the-class-fix yet with GCM being so unstable, that my device won't receive push messages atm.
Can anyone confirm this has actually been fixed? I'm not using AsyncTask - I'm using an EventBus to post events to my app's Activities if any is alive and that part works fine except for when I'm trying to show a Toast for instance, then I'm getting the exception in LogCat. I receive the event from my EventBus though.
I haven't tried the "touching"-the-class-fix yet with GCM being so unstable, that my device won't receive push messages atm.
ju...@gmail.com <ju...@gmail.com> #20
Do we have an official release version for this fix? Or clarification if it is still necessary since there seems to still be some reports?
[Deleted User] <[Deleted User]> #21
Fix is still needed strictly before Jelly Bean:
"The AsyncTask class must be loaded on the UI thread. This is done automatically as of JELLY_BEAN." [1]
1.https://developer.android.com/reference/android/os/AsyncTask.html
"The AsyncTask class must be loaded on the UI thread. This is done automatically as of JELLY_BEAN." [1]
1.
Description
private static final InternalHandler sHandler = new InternalHandler();
It expects this to be initialized on the main thread, but that is not guaranteed since it will be initialized on whichever thread happens to cause the class to run its static initializers. I reproduced this issue where the Handler references a worker thread.
I attached screenshots of the debugger watch window showing this happening in a live program, A symptom of this happening is the following stack trace:
W/MessageQueue( 5328): Handler{40797d88} sending message to a Handler on a dead thread
W/MessageQueue( 5328): java.lang.RuntimeException: Handler{40797d88} sending message to a Handler on a dead thread
W/MessageQueue( 5328): at android.os.MessageQueue.enqueueMessage(MessageQueue.java:196)
W/MessageQueue( 5328): at android.os.Handler.sendMessageAtTime(Handler.java:457)
W/MessageQueue( 5328): at android.os.Handler.sendMessageDelayed(Handler.java:430)
W/MessageQueue( 5328): at android.os.Handler.sendMessage(Handler.java:367)
W/MessageQueue( 5328): at android.os.Message.sendToTarget(Message.java:349)
W/MessageQueue( 5328): at android.os.AsyncTask$3.done(AsyncTask.java:214)
W/MessageQueue( 5328): at java.util.concurrent.FutureTask$Sync.innerSet(FutureTask.java:253)
W/MessageQueue( 5328): at java.util.concurrent.FutureTask.set(FutureTask.java:113)
W/MessageQueue( 5328): at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:311)
W/MessageQueue( 5328): at java.util.concurrent.FutureTask.run(FutureTask.java:138)
W/MessageQueue( 5328): at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1088)
W/MessageQueue( 5328): at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:581)
W/MessageQueue( 5328): at java.lang.Thread.run(Thread.java:1019)
A common pattern that causes this to happen is using the class IntentService. The C2DM sample code does this. I can reproduce this 100% of the time in my app by killing the app and then sending it a C2DM message which results in AsyncTask being initialized in the C2DM IntentService worker thread.
A simple workaround is to add the following code to the application's onCreate method:
new AsyncTask<Void, Void, Void>() {
@Override
protected Void doInBackground(Void... params) {
return null;
}
}.execute();
This will force AsyncTask to be initialized in the main thread.