Android应用程序在崩溃/强制关闭时重新启动

Tec*_*ist 41 crash stack android forceclose

我的android应用程序在强制关闭后重新启动,通过我的整个应用程序,包括20个活动,我依赖于在主要活动上创建的静态数据.因此,一旦应用程序崩溃,我的所有静态数据都会丢失,当应用程序自动重启时,它几乎没有任何基本数据可供操作.

我的问题是,在崩溃时我希望这件事发生

  1. 如果应用程序崩溃,我不希望应用程序重新启动,而我希望与此应用程序相关的所有堆栈/任务都被清除内存.用户可以再次从头重新启动它
  2. 如果我无法阻止应用重启,至少我想保留基本数据,以便在应用重启时我可以将它们分配回来.此外,当它重新启动时,我希望我的应用程序从主要活动开始.

我知道当活动崩溃时,android系统会将堆栈中的下一个活动带到前台,这就是我的应用程序产生冗余结果的原因.我也经历了Android开发人员,但我唯一知道的是在Manifest中设置一个属性android:finishOnTaskLaunch="true".但不幸的是,这对我毫无帮助.我非常感谢你帮助解决这个问题,并让我知道原因和分析.

Arc*_*pgc 51

  1. 最好的解决方案是使用静态数据,Shared Preferences在a中使用或存储数据Database,如果有的话uncaught Exception,显示消息Application has crashed and a report is sent to the admin,然后重新启动导致崩溃的Activity.这样用户可以继续使用该应用程序.

  2. 执行相同操作,但不是重新启动导致Exception的Activity重新启动应用程序.

创建一个用于处理的类 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);
    }
}
Run Code Online (Sandbox Code Playgroud)

并在每个Activity中创建此类的Object并将其设置为 DefaultUncaughtExceptionHandler

    Thread.setDefaultUncaughtExceptionHandler(new MyExceptionHandler(this,
            YourCurrentActivity.class));
Run Code Online (Sandbox Code Playgroud)

  • @Satheesh尝试`import android.os.Process;`以避免与默认的`java.lang.Process`冲突. (11认同)
  • 实际上你并不需要在每个活动中都使用它,因为它是Thread的UncaughtExceptionHandler,你只需要在每个线程上执行一次.因此,如果您的所有活动始终在同一主线程上运行(通常是这种情况),则只需在启动器活动上使用Thread.setDefaultUncaughtExceptionHandler (3认同)

Pau*_*aul 8

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 );
        }
    }
}
Run Code Online (Sandbox Code Playgroud)