Frage Android App wird nach Absturz neu gestartet


Meine Android-App wird nach dem Schließen der Gewalt neu gestartet. Durch meine gesamte Anwendung, die aus 20 Aktivitäten besteht, vertraue ich auf statische Daten, die für eine Hauptaktivität erstellt wurden. Sobald die App abgestürzt ist, gehen alle meine statischen Daten verloren und wenn die App automatisch neu startet, hat sie keine wesentlichen Daten mehr.

Meine Frage ist, nach dem Absturz möchte ich, dass diese Dinge passieren

  1. Wenn die App abstürzt, möchte ich nicht, dass die App neu gestartet wird. Stattdessen möchte ich, dass alle Stapel / Aufgaben, die mit dieser App in Zusammenhang stehen, aus dem Speicher gelöscht werden. Ein Benutzer kann es von Anfang an neu starten
  2. Wenn ich nicht verhindern kann, dass die App neu gestartet wird, möchte ich zumindest wichtige Daten beibehalten, damit ich sie beim Neustart der App wieder zuordnen kann. Auch wenn es neu startet, möchte ich, dass meine App von der Hauptaktivität startet.

Ich weiß, wenn die Aktivität abstürzt android System bringt die nächste Aktivität im Stapel in den Vordergrund, und das ist der Grund für meine App, die redundante Ergebnisse produziert. Ich habe auch die Android-Entwickler durchforstet, aber das Einzige, was ich gelernt habe, war, ein Attribut in Manifest einzurichten android:finishOnTaskLaunch="true". Aber das hilft mir leider nicht. Ich würde Ihre Hilfe bei der Lösung dieses Problems zu schätzen wissen und mich auch über die Ursache und die Analyse informieren.


29
2017-09-24 07:29


Ursprung


Antworten:


  1. Beste Lösung wäre, anstatt statische Daten zu verwenden, zu verwenden Shared Preferences oder speichern Sie Daten in a Database und falls vorhanden uncaught Exception tritt auf, zeige eine Nachricht wie Application has crashed and a report is sent to the admin und dann die Aktivität, die den Absturz verursacht hat, neu starten. Auf diese Weise kann der Benutzer die Anwendung weiter verwenden.

  2. Führen Sie das gleiche aus, aber starten Sie die Anwendung, die die Ausnahme verursacht hat, neu.

Erstelle eine Klasse, die benutzt wird 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);
    }
}

und in jeder Aktivität erstellen Sie ein Objekt dieser Klasse und legen Sie es als das DefaultUncaughtExceptionHandler

    Thread.setDefaultUncaughtExceptionHandler(new MyExceptionHandler(this,
            YourCurrentActivity.class));

43
2017-09-24 07:45



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 );
        }
    }
}

8
2018-02-12 19:47



  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....

(Referenz: Archie.bpgc)


2
2018-01-11 09:47



Wenn der Nutzer Ihre App zwingt, die App zu beenden (über Einstellungen> Apps> App-Info oder aus der Liste der zuletzt verwendeten Apps) oder das Betriebssystem die App stoppt, können Sie mit Hilfe speichern, was Sie benötigen onSaveInstanceState().

Wenn Ihre App jedoch abstürzt, können Sie nicht viel dagegen tun (abgesehen davon, dass wichtige Daten regelmäßig in den Einstellungen / Datenbanken / etc. Gespeichert werden). Es ist wahrscheinlich besser, sich darauf zu konzentrieren, Abstürze zu vermeiden, als mit Abstürzen umzugehen!


1
2017-09-24 07:41



Speichern Sie Daten nicht in statischen Feldern. Ihr Prozess konnte bei einem Ereignis mit wenig Speicher beendet werden und Sie werden alles verlieren. Ihre Aktivitäten werden aus dem gespeicherten Status wiederhergestellt, wenn der Benutzer erneut zu Ihrer App wechselt, Ihre statischen Variablen jedoch nicht wiederhergestellt werden.


1
2017-09-20 17:16



Nun, eine Anwendung ist nicht nur Schnittstelle (Aktivitäten). Stellen Sie sich vor, Sie haben eine komplexe Unternehmensanwendung, die SQL-Transaktionen, Sicherheit, Web-Authentifizierung usw. verwendet. Es ist fast unmöglich, jede Aktivität in die Lage zu versetzen, den gesamten App-Kontext nur mit gemeinsamen Einstellungen wiederherzustellen. In diesem Fall verwende ich diesen 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();
    /*
    ....
    */
 }
/*
    ....
*/
}

1
2017-12-01 09:14



Meine App wurde auch mit einem leeren Bildschirm fortgesetzt, als es abgestürzt war. Um dies zu beheben, habe ich das savedInstanceState-Objekt auf OnCreate-Methode meiner Hauptaktivität überprüft und wenn es nicht Null ist (bedeutet, dass es von Android-System neu gestartet wird), dann beendete ich meine Aktivität. So ähnlich:

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    if (savedInstanceState != null) {
        finish();
    }
}

Es kann auch in Ihrem Fall helfen.


0
2018-01-07 06:47