25

I have an app and if the app crashes in a particular activity, it restarts at one of the intermediate parent activities.

This is a problem for me since I have some inputted user info that is lost upon crash.

Is there any way to force the app to start from the launcher screen after restarting from a crash?

Thanks.

ElGavilan
  • 6,610
  • 16
  • 27
  • 36
Wise Shepherd
  • 2,228
  • 4
  • 31
  • 43
  • Have you tried to omit the android.intent.category.DEFAULT category from that particular Activity? This probably only works if you don't want to launch the activity with implicit intents. – Denis Loh Jan 08 '15 at 10:28
  • @DenisLoh this won't help. Standard Android behaviour is to restart the app at the Activity before the one that crashed. This has nothing to do with manifest settings and you cannot change this behaviour. – David Wasser Jan 09 '15 at 11:27
  • Fix your app so it doesn't crash. Catch exceptions where needed and do something intelligent. There is no workaround for code that isn't robust, except making your code more robust. – David Wasser Jan 09 '15 at 11:28
  • 3
    @DavidWasser you're right. However, you'll never write apps which never crash. So, instead and if it is really required you may also try a custom UncaughtExceptionHandler and restart your activity from there. This must be done with care, as an error in that activity would cause infinite loops. – Denis Loh Jan 09 '15 at 11:36

5 Answers5

17

Proposed Solution 1 -

Add this tag android:clearTaskOnLaunch="true" in the manifest.xml file to your main activity which should always launch.

Probable Reason why it did not work

When the application crashes, it throws an Exception and we need to handle the Exception and otherwise we would not get the expected behavior

Proposed Solution 2

Try to handle any uncaught Exception and tell the system what to do. To implement this, try the below steps.

  1. Create a class extending Application Class
  2. Handle uncaughtException in your Application subclass.
  3. In your launcher Activity, call your Application class.
  4. After catching an Exception, start your main Activity (as per your requirement).

Code Sample

Step 1 and 2

package com.casestudy.intentsandfilter;

import android.app.Application;
import android.content.Intent;

public class MyApplication extends Application
{
    @Override
    public void onCreate() {

        super.onCreate();

        Thread.setDefaultUncaughtExceptionHandler(
            new Thread.UncaughtExceptionHandler() {
                @Override
                public void uncaughtException (Thread thread, Throwable e) {
                    handleUncaughtException (thread, e);
                }
            });
    }

    private void handleUncaughtException (Thread thread, Throwable e) {

        // The following shows what I'd like, though it won't work like this.
        Intent intent = new Intent (getApplicationContext(),DrawView.class);
        startActivity(intent);

        // Add some code logic if needed based on your requirement
    }
}

Step 3

public class MainActivity extends Activity {

    protected MyApplication app;

    @Override
    public void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);

        setContentView(R.layout.main);

        // Get the application instance
        app = (MyApplication)getApplication();

        .............
    }
}

Step 4

Modify the below method as per your requirement

private void handleUncaughtException (Thread thread, Throwable e) {

    // The following shows what I'd like, though it won't work like this.
    Intent intent = new Intent (getApplicationContext(), HomeActivity.class);
    startActivity(intent);

    // Add some code logic if needed based on your requirement
}
Cory Roy
  • 5,379
  • 2
  • 28
  • 47
Prem
  • 4,823
  • 4
  • 31
  • 63
17

I would recommend using library such as

https://github.com/Ereza/CustomActivityOnCrash

As the library takes care of other stuff along with different versions of android.

enter image description here

Pradeep Kumar Kushwaha
  • 2,231
  • 3
  • 23
  • 34
7

First, create and set the App class in your AndroidManifest.xml and

android:name=".App"
android:clearTaskOnLaunch="true"

then put this code in the App class

public class App extends Application {
@Override
public void onCreate() {
    super.onCreate();
     Thread.setDefaultUncaughtExceptionHandler(
            new Thread.UncaughtExceptionHandler() {
                @Override
                public void uncaughtException(Thread thread, Throwable e) {
                    Log.d("AppCrash", "Error just lunched ");
                }
            });
}}

Debug Log Screenshot:
Debug Log Screenshot

Abhimanyu
  • 11,351
  • 7
  • 51
  • 121
Hakim Douib
  • 495
  • 1
  • 6
  • 13
1

Maybe there's no way to do that but you can flag it so you know if the activity was started through user action or if it was just started after a crash.

i.e when you start the parent activity, pass something into the startActivity intent. If that isn't there then it was started after the crash.

imorsi
  • 346
  • 1
  • 11
1

I managed to start my main activity with intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); like this:

private void handleUncaughtException (Thread thread, Throwable e)
  {
    Intent intent = new Intent (getApplicationContext(), MainActivity.class);
    intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
    startActivity(intent);
  }
Adrian
  • 717
  • 11
  • 18