Android App Restarts upon Crash/force close

前端 未结 7 971
名媛妹妹
名媛妹妹 2020-12-07 10:10

My android app is getting restarted after force close, through my entire application which consist of 20 activities, I am relying on static data created on a main activity.

相关标签:
7条回答
  • 2020-12-07 10:22
    1. Best solution would be instead of using Static data, use Shared Preferences or store data in a Database and if any uncaught Exception occurs, show a message like Application has crashed and a report is sent to the admin and then restart the Activity that caused the Crash. This way user can continue using the application.

    2. Do the same but instead of restarting the Activity which caused the Exception restart the application.

    create a class used to handle unCaughtException

    public class MyExceptionHandler implements
            java.lang.Thread.UncaughtExceptionHandler {
        private final Context myContext;
        private final Class<?> myActivityClass;
    
        public MyExceptionHandler(Context context, Class<?> c) {
    
            myContext = context;
            myActivityClass = c;
        }
    
        public void uncaughtException(Thread thread, Throwable exception) {
    
            StringWriter stackTrace = new StringWriter();
            exception.printStackTrace(new PrintWriter(stackTrace));
            System.err.println(stackTrace);// You can use LogCat too
            Intent intent = new Intent(myContext, myActivityClass);
            String s = stackTrace.toString();
            //you can use this String to know what caused the exception and in which Activity
            intent.putExtra("uncaughtException",
                    "Exception is: " + stackTrace.toString());
            intent.putExtra("stacktrace", s);
            myContext.startActivity(intent);
            //for restarting the Activity
            Process.killProcess(Process.myPid());
            System.exit(0);
        }
    }
    

    and in every Activity create an Object of this class and set it as the DefaultUncaughtExceptionHandler

        Thread.setDefaultUncaughtExceptionHandler(new MyExceptionHandler(this,
                YourCurrentActivity.class));
    
    0 讨论(0)
  • 2020-12-07 10:22

    My app was also getting resumed with blank screen, when it was getting crashed. To resolve this, I checked the savedInstanceState object on onCreate method of my main activity and if it is not null (means it is restarted by android system) then I finished my activity. Something like that:

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    
        if (savedInstanceState != null) {
            finish();
        }
    }
    

    It may help in your case too.

    0 讨论(0)
  • 2020-12-07 10:25

    Well, an application is not only interface(activities). Imagine you have some complex enterprise application, using SQL transactions, security, Web Authentication, etc.. It is almost impossible to make each activity able to recover the whole app context using only Shared Preferences. So in this case, I use this piece of Code:

    public class MyApplication extends Application {
      private static final String TAG = "my.app";   
      public static final String MainActivityName = "my.app.top.activity";
    
      @Override
      public void onCreate() {
    
        try{
            ActivityManager am = (ActivityManager) this .getSystemService(ACTIVITY_SERVICE);
            List<ActivityManager.RunningTaskInfo> taskInfo = am.getRunningTasks(1);
            ComponentName componentInfo = taskInfo.get(0).topActivity;
            if (MainActivityName.length()>0 && !componentInfo.getClassName().equals(MainActivityName)){
                Log.d(TAG, "Partial Restart Not Supported! : " +componentInfo.getClassName());
                android.os.Process.killProcess(android.os.Process.myPid());
                System.exit(0);
                return;
            }else
                Log.d(TAG, "!!! BCSApplication topActivity=" +componentInfo.getClassName());
        }catch(Exception eee){}
    
        super.onCreate();
        /*
        ....
        */
     }
    /*
        ....
    */
    }
    
    0 讨论(0)
  • 2020-12-07 10:31

    Do not store data in static fields. Your process could be stopped on low memory event and you will lost everything. Your activities will be restored from saved state if user switch to your app again, but your static variables will not get restored.

    0 讨论(0)
  • 2020-12-07 10:39
    public class MyApp extends Application {
        private static final String TAG = "MyApp";
        private static final String KEY_APP_CRASHED = "KEY_APP_CRASHED";
    
        @Override
        public void onCreate() {
            super.onCreate();
    
            final UncaughtExceptionHandler defaultHandler = Thread.getDefaultUncaughtExceptionHandler();
            Thread.setDefaultUncaughtExceptionHandler( new UncaughtExceptionHandler() {
                @Override
                public void uncaughtException(Thread thread, Throwable exception) {
                    // Save the fact we crashed out.
                    getSharedPreferences( TAG , Context.MODE_PRIVATE ).edit()
                        .putBoolean( KEY_APP_CRASHED, true ).apply();
                    // Chain default exception handler.
                    if ( defaultHandler != null ) {
                        defaultHandler.uncaughtException( thread, exception );
                    }
                }
            } );
    
            boolean bRestartAfterCrash = getSharedPreferences( TAG , Context.MODE_PRIVATE )
                    .getBoolean( KEY_APP_CRASHED, false );
            if ( bRestartAfterCrash ) {
                // Clear crash flag.
                getSharedPreferences( TAG , Context.MODE_PRIVATE ).edit()
                    .putBoolean( KEY_APP_CRASHED, false ).apply();
                // Re-launch from root activity with cleared stack.
                Intent intent = new Intent( this, MyRootActivity.class );
                intent.addFlags( Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_NEW_TASK );
                startActivity( intent );
            }
        }
    }
    
    0 讨论(0)
  • 2020-12-07 10:41
      setContentView(R.layout.current);
    
      Thread.setDefaultUncaughtExceptionHandler(new UncaughtExceptionHandler() {
    
      @Override
      public void uncaughtException(Thread t, Throwable e) {
            android.os.Process.killProcess(android.os.Process.myPid());
            System.exit(0);
      }
    
      code....
    

    (reference: Archie.bpgc)

    0 讨论(0)
提交回复
热议问题