Search code examples
androidandroid-activityandroid-pendingintent

New activity sometimes doesn't start


In certain circumstances I need to call exit() in my application (I know it's not the best way to finish but this is not the question). Also I want to show a new dialog which informs the user about the crash.

I created a new activity class, a new broadcast receiver, registered them in manifest. Next, I call:

Intent intent = new Intent(this, AppCloseReceiver.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(this.getApplicationContext(), 0, intent, 0);
try
{
    pendingIntent.send();
}
catch(Exception ex){}

System.exit(0);

The problem is that new window appears sometimes! First I thought that System.exit(0); fires before new activity have a chance to start (because of async call, thought couldn't find this in documentation) so I added Thread.sleep(1000) between pendingIntent.send(); and System.exit(0);, but the result is the same - new window appears sometimes. There's nothing in the logs, no exception.

The new activity is just a static text.


Solution

  • This isn't reliable. If you cause the VM to shutdown you cannot display anything, as there is no longer a VM running. The only reliable way to do this would be to ensure the BroadcastReceiver and Activity run in a different OS process to display your message. This also isn't 100% reliable, because depending on the nature of the exception, your existing VM may not be able to start the other components, but it is probably more reliable than your current implementation. For example, if your app crashes due to OutOfMemoryException, it probably isn't possible to do anything useful.

    To ensure that a component runs in a separate process, add

    android:process=":other"
    

    to the <activity> and <receiver> definitions in the manifest for those components.

    You should also try to delay the call to System.exit() to give the VM a chance to actually initiate the launch of the dialog. Also, you don't need to use a PendingIntent for this. Try something like this:

    Intent intent = new Intent(this, AppCloseReceiver.class);
    sendBrodcast(intent);
    // Start separate Thread to terminate the process
    new Thread(new Runnable() {
        @override
        public void run() {
            SystemClock.sleep(1000); // Sleep a bit to give the VM enough time to actually send the broadcast Intent
            System.exit(0);
        }
    }).start();