onPostExecute n'étant pas appelé dans AsyncTask (exception d'exécution du gestionnaire)

J'ai un AsyncTask qui extrait des données et ensuite les mises à jour de l'INTERFACE utilisateur avec ces nouvelles données. Il a été fonctionne bien depuis des mois, mais j'ai récemment ajouté une fonctionnalité qui permet d'afficher une notification lorsqu'il y a de nouvelles données. Maintenant, quand mon application est lancée par le biais de la notification, parfois, je reçois cette exception et onPostExecute n'est pas appelé.

C'est ce qui arrive lorsque l'application est lancée:

1) Développer l'INTERFACE utilisateur et de trouver des points de vue

2) Annuler l'alarme (par AlarmManager) qui vérifie la présence de nouvelles données et réinitialisation de l'alarme. (C'est ainsi que si l'utilisateur désactive l'alarme il est annulé avant la prochaine fois qu'il/elle redémarre.)

3) Démarrer le AsyncTask. Si l'application a été lancée à partir de la notification, passer un peu de bits de données, puis annuler la notification.

Je suis coincé sur ce qui pourrait être la cause de cette exception. Il semble que l'exception est de la AsyncTask code, donc je ne suis pas sûr de savoir comment je peux le résoudre.

Merci!

Ici est l'exception:

I/My App(  501): doInBackground exiting
W/MessageQueue(  501): Handler{442ba140} sending message to a Handler on a dead thread
W/MessageQueue(  501): java.lang.RuntimeException: Handler{442ba140} sending message to a Handler on a dead thread
W/MessageQueue(  501):  at android.os.MessageQueue.enqueueMessage(MessageQueue.java:179)
W/MessageQueue(  501):  at android.os.Handler.sendMessageAtTime(Handler.java:457)
W/MessageQueue(  501):  at android.os.Handler.sendMessageDelayed(Handler.java:430)
W/MessageQueue(  501):  at android.os.Handler.sendMessage(Handler.java:367)
W/MessageQueue(  501):  at android.os.Message.sendToTarget(Message.java:348)
W/MessageQueue(  501):  at android.os.AsyncTask$3.done(AsyncTask.java:214)
W/MessageQueue(  501):  at java.util.concurrent.FutureTask$Sync.innerSet(FutureTask.java:252)
W/MessageQueue(  501):  at java.util.concurrent.FutureTask.set(FutureTask.java:112)
W/MessageQueue(  501):  at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:310)
W/MessageQueue(  501):  at java.util.concurrent.FutureTask.run(FutureTask.java:137)
W/MessageQueue(  501):  at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1068)
W/MessageQueue(  501):  at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:561)
W/MessageQueue(  501):  at java.lang.Thread.run(Thread.java:1096)

EDIT: Voici mon onCreate méthode dans mon activité principale (celle ouverte par la notification). Il y a quelques onClickListeners que j'ai omis d'économiser de l'espace. Je ne pense pas qu'ils devraient avoir aucun effet, puisque les boutons ils sont attachés ne sont pas pressés.

@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState); //Call the parent
setContentView(R.layout.main); //Create the UI from the XML file
//Find the UI elements
controls = (SlidingDrawer) findViewById(R.id.drawer); //Contains the
//buttons
//comic = (ImageView) findViewById(R.id.comic); //Displays the comic
subtitle = (TextView) findViewById(R.id.subtitleTxt); //Textbox for the
//subtitle
prevBtn = (Button) findViewById(R.id.prevBtn); //The previous button
nextBtn = (Button) findViewById(R.id.nextBtn); //The next button
randomBtn = (Button) findViewById(R.id.randomBtn); //The random button
fetchBtn = (Button) findViewById(R.id.comicFetchBtn); //The go to specific id button
mostRecentBtn = (Button) findViewById(R.id.mostRecentBtn); //The button to go to the most recent comic
comicNumberEdtTxt = (EditText) findViewById(R.id.comicNumberEdtTxt); //The text box to Zooming image view setup
zoomControl = new DynamicZoomControl();
zoomListener = new LongPressZoomListener(this);
zoomListener.setZoomControl(zoomControl);
zoomComic = (ImageZoomView) findViewById(R.id.zoomComic);
zoomComic.setZoomState(zoomControl.getZoomState());
zoomComic.setImage(BitmapFactory.decodeResource(getResources(), R.drawable.defaultlogo));
zoomComic.setOnTouchListener(zoomListener);
zoomControl.setAspectQuotient(zoomComic.getAspectQuotient());
resetZoomState();
//enter the new id
imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE); //Used to hide the soft keyboard
Log.i(LOG_TAG, "beginning loading of first comic");
int notificationComicNumber = getIntent().getIntExtra("comic", -1);
Log.i(LOG_TAG, "comic number from intent: " + notificationComicNumber);
if (notificationComicNumber == -1) {
fetch = new MyFetcher(this, zoomComic, subtitle, controls, comicNumberEdtTxt, imm, zoomControl);
fetch.execute(MyFetcher.LAST_DISPLAYED_COMIC);
} else {
fetch = new MyFetcher(this, zoomComic, subtitle, controls, comicNumberEdtTxt, imm, zoomControl);
fetch.execute(notificationComicNumber);
((NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE)).cancelAll();
}
Log.i(LOG_TAG, "ending loading of new comic");
Log.i(LOG_TAG, "first run checks beginning");
//Get SharedPreferences
prefs = getSharedPreferences("prefs", Context.MODE_PRIVATE);
//Check if this is the first run of the app for this version
if (prefs.getBoolean("firstRun-" + MAJOR_VERSION_NUMBER, true)) {
prefs.edit().putBoolean("firstRun-" + MAJOR_VERSION_NUMBER, false).commit();
firstRunVersionDialog();
}
//Check if this is the first run of the app
if (prefs.getBoolean("firstRun", true)) {
prefs.edit().putBoolean("firstRun", false).commit();
firstRunDialog();
}
Log.i(LOG_TAG, "First run checks done");
//OnClickListener s for the buttons omitted to save space

EDIT 2: j'ai été fouiller dans le code source Android de suivi en bas où l'exception est à venir. C'est les lignes de 456 et 457 de sendMessageAtTime dans Handler:

msg.target = this;
sent = queue.enqueueMessage(msg, uptimeMillis);

Et c'est enqueueMessage de MessageQueue:

    final boolean enqueueMessage(Message msg, long when) {
if (msg.when != 0) {
throw new AndroidRuntimeException(msg
+ " This message is already in use.");
}
if (msg.target == null && !mQuitAllowed) {
throw new RuntimeException("Main thread not allowed to quit");
}
synchronized (this) {
if (mQuiting) {
RuntimeException e = new RuntimeException(
msg.target + " sending message to a Handler on a dead thread");
Log.w("MessageQueue", e.getMessage(), e);
return false;
} else if (msg.target == null) {
mQuiting = true;
}
msg.when = when;
//Log.d("MessageQueue", "Enqueing: " + msg);
Message p = mMessages;
if (p == null || when == 0 || when < p.when) {
msg.next = p;
mMessages = msg;
this.notify();
} else {
Message prev = null;
while (p != null && p.when <= when) {
prev = p;
p = p.next;
}
msg.next = prev.next;
prev.next = msg;
this.notify();
}
}
return true;
}

Je suis un peu confus au sujet de ce mQuiting est, mais il semble que la fois précédente enqueueMessage a été appelé msg.target était nulle.

source d'informationauteur Computerish