In conjunction a previous question
of mine, I would like to know exactly what happens to a context when an exception is caught by a Thread.UncaughtExceptionListener. When the uncaught exception is received by the listener, the context seems to have fallen into a limbo state. It has access to some of its methods (primarily the ones pertaining to resources), but then a great many don’t work (or don’t visibly work). This includes (but isn’t limited to, I’m sure there are more I haven’t found):
Toast(as in my link)Dialog- Creation of new activities. This includes normal
Context.startActivity(Intent)andPendingIntent.
However the context still has apparent access to contextual resources (getString(), Resources and oddly enough Notifications).
Why is this? What causes this state imbalance(?) in the context to prevent any context driven calls?
Below I have created a test application for you that is suppose to launch an error activity when an exception is left uncaught. To test the things I have mentioned (Toast and dialog) in the situation I have been doing, place their builders in the BoomMitActivity in lieu of the notification builder.
In the given example, the activity error out (how could it not?) and launches BoomMitActivtiy when the Notification is clicked. However, BoomMit’s onCreate is never called.
Application:
public class AndroidTestoActivity extends Activity implements UncaughtExceptionHandler {
@Override public void onCreate(Bundle icicle) {
super.onCreate(icicle);
Thread.setDefaultUncaughtExceptionHandler(this);
throw new RuntimeException("HAHAHAHA, I broke you");
}
@Override public void uncaughtException(Thread arg0, Throwable arg1) {
finish();
NotificationManager nm = (NotificationManager)getSystemService(Context.NOTIFICATION_SERVICE);
Notification note = new Notification(R.drawable.ic_launcher, "Boom!", System.currentTimeMillis());
Intent i = new Intent(this, BoomMitActivity.class);
i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
PendingIntent pi = PendingIntent.getActivity(this, 1, i, PendingIntent.FLAG_ONE_SHOT);
note.setLatestEventInfo(this, "Boom!", "Open BoomMitActivity", pi);
note.flags |= Notification.FLAG_AUTO_CANCEL;
nm.notify(1, note);
Log.d("TAG", "End");
}
static class BoomMitActivity extends Activity {
@Override public void onCreate(Bundle icicle) {
super.onCreate(icicle);
TextView tv = new TextView(this);
tv.setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT));
tv.setBackgroundColor(0xffff0000);
tv.setText("BoomMitActivity is the one true activity");
tv.setTextColor(0xff00ffff);
setContentView(tv);
}
}
}
Manifest:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.testo"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk android:minSdkVersion="8" />
<application
android:icon="@drawable/ic_launcher"
android:label="@string/app_name" >
<activity
android:name=".AndroidTestoActivity"
android:label="@string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name="AndroidTestoActivity$BoomMitActivity"
android:label="I'm a real boy!"
android:taskAffinity=""
android:excludeFromRecents="true"
android:launchMode="singleTask">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
</application>
</manifest>
Nothing happens to Context itself. If you are talking about when you are in the situation where the app crash dialog is up, then the crashing thread is sitting there waiting for the user to press a button and let it proceed to kill itself. At this point the system knows your app is trashed, and is just waiting for the user to confirm and finally terminate it. So you really should assume you are on the way out and not rely on much of anything working.
Further, if this crash came from the main thread, then that thread is now sitting there blocked waiting for the user to confirm the crash dialog so it can commit suicide. It is not sitting there processing its message loop, it is sitting there completely blocked waiting for suicide. No work that would be scheduled on that thread will execute. For the main thread, this includes callbacks on components like Activity.onCreate(), Service.onStart(), and on and on. For any thread, this includes dispatching any work for window UIs associated with the thread. Again if this is the main thread, this probably means all of your UI.