55

20 のアクティビティで構成されるアプリケーション全体を通じて、強制終了後に Android アプリが再起動されます。メイン アクティビティで作成された静的データに依存しています。そのため、アプリがクラッシュすると、すべての静的データが失われ、アプリが実質的に自動再起動すると、操作するための重要なデータがなくなります。

私の質問は、クラッシュ時にこれが起こることを望んでいるということです

  1. アプリがクラッシュした場合、アプリを再起動するのではなく、このアプリに関連するすべてのスタック/タスクをメモリから消去したい. ユーザーは最初からやり直すことができます
  2. アプリの再起動を防ぐことができない場合は、少なくとも重要なデータを保持して、アプリの再起動時にそれらを元に戻すことができるようにしたいと考えています。また、再起動するときに、アプリをメイン アクティビティから開始したいと考えています。

アクティビティが Android システムをクラッシュさせると、スタック内の次のアクティビティがフォアグラウンドに移動することを知っています。これが、アプリが冗長な結果を生成する理由です。また、私はアンドロイド開発者を調べましたが、私が知ったのは Manifest で属性を設定することだけでしたandroid:finishOnTaskLaunch="true"。しかし、残念ながら、これは私には役に立ちません。この問題を解決するためのご協力と、原因と分析をお知らせいただければ幸いです。

4

7 に答える 7

60
  1. 最善の解決策は、静的データを使用する代わりに、データを使用Shared Preferencesまたは保存し、Database何かuncaught Exceptionが発生した場合は、次のようなメッセージを表示しApplication has crashed and a report is sent to the adminて、クラッシュの原因となったアクティビティを再起動することです。このようにして、ユーザーはアプリケーションを引き続き使用できます。

  2. 同じことを行いますが、例外の原因となったアクティビティを再起動する代わりに、アプリケーションを再起動します。

処理に使用するクラスを作成する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);
    }
}

すべてのアクティビティで、このクラスのオブジェクトを作成し、それをDefaultUncaughtExceptionHandler

    Thread.setDefaultUncaughtExceptionHandler(new MyExceptionHandler(this,
            YourCurrentActivity.class));
于 2012-09-24T07:45:22.830 に答える
9
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 );
        }
    }
}
于 2014-02-12T19:47:12.717 に答える
4
  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....

(参考:Archie.bpgc)

于 2013-01-11T09:47:05.697 に答える
3

静的フィールドにデータを格納しないでください。メモリ不足のイベントでプロセスが停止する可能性があり、すべてが失われます。ユーザーが再びアプリに切り替えると、アクティビティは保存された状態から復元されますが、静的変数は復元されません。

于 2014-09-20T17:16:26.420 に答える
0

ユーザーが ([設定] > [アプリ] > [アプリ情報] から、または最近使用したアプリの一覧から) アプリを強制的に停止している場合、またはオペレーティング システムがアプリを停止している場合は、onSaveInstanceState().

ただし、アプリがクラッシュした場合、それについてできることはあまりありません (重要なものを設定/データベースなどに定期的に保存することを除いて)。クラッシュを処理しようとするよりも、クラッシュを防ぐことに集中する方がおそらく良いでしょう!

于 2012-09-24T07:41:05.833 に答える