Android:「強制終了」後にアプリケーションを自動再起動するにはどうすればよいですか?


81

Androidアプリケーションでは、例外を適切に処理しなかった場合、通常、「強制終了」エラーが発生しました。

アプリケーションが強制的に閉じられた場合、どうすればアプリケーションを自動的に再起動できますか?

これに使用される特定の許可はありますか?


5
例外を正しく取得するようにしてください。自動的に再起動するアプリケーションは、ユーザーを煩わせる可能性があります。
Tomas Andrle 2010

12
アプリケーションがクラッシュした場合は、アプリケーションを再起動したいだけです。特にユーザーが私のアプリケーションを使用している場合は、煩わしいよりもフレンドリーだと思います。そして、はい、私はすべての例外を正しく取得しようとしています。:)
ジョニー

2
@ジョニー:あなたの問題の解決策を共有してください。
code_Life 2012

この記事を確認して、例外が発生した場合にアプリケーションを再起動してください。
Chintan Rathod 2015年

回答:


100

これを達成するには、2つのことを行う必要があります。

  1. アプリケーションがクラッシュする標準的な方法である「強制終了」は避けてください。
  2. とにかくクラッシュが発生したときに再起動メカニズムを設定します。

これらを行う方法を以下に示します。

  1. Thread.setDefaultUncaughtExceptionHandler()キャッチされなかったすべての例外をキャッチするために呼び出しuncaughtException()ます。この場合、メソッドが呼び出されます。「強制終了」は表示されず、アプリケーションが応答しなくなります。これはあまり良いことではありません。クラッシュしたときにアプリケーションを再起動するには、次の手順を実行する必要があります。

  2. このonCreateメソッドでは、メインアクティビティでPendingIntentメンバーを初期化します。

    Intent intent = PendingIntent.getActivity(
        YourApplication.getInstance().getBaseContext(),
        0,
        new Intent(getIntent()),
        getIntent().getFlags());
    

次に、uncaughtException()メソッドに次のように入力します。

AlarmManager mgr = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
mgr.set(AlarmManager.RTC, System.currentTimeMillis() + 2000, intent);
System.exit(2);

また、電話する必要があります System.exit()。そうしないと機能しません。このようにして、アプリケーションは2秒後に再起動します。

最終的には、アプリケーションがクラッシュしたことを意図してフラグを設定し、onCreate()メソッドで「申し訳ありませんが、アプリケーションがクラッシュしました。二度とないことを願っています:)」というダイアログを表示できます。


4
私はそれを理解しました。今問題はuncaughtExceptionメソッドをどこに実装するかです?? plzヘルプ。ありがとう。
ジェイ真由

2
@MayuMayooresanアプリケーションクラスまたはActivityを拡張して、onCreate()で次の操作を実行できます。Thread.setDefaultUncaughtExceptionHandler(new UncaughtExceptionHandler(){...});
AgentKnopf 2012

1
アクティビティを拡張する場合は、アプリケーションのエントリポイントとして機能できるすべてのアクティビティ(Android OSが起動を決定する可能性のあるアクティビティを含む-たとえば、ウィンドウが停止したときなど)に対して同じことを行う必要があることに注意してください
ミック

1
アプリの管理メニューからプロセスを強制的に停止した後、ICSでは機能しないようです。
sunghun 2012年

5
YourApplicationとはどういう意味ですか?@Maheshのアドバイスを使用しましたが、機能しませんでした。誰かがそれを説明してください。
Shervin Gharib 2015年

16

秘訣は、そもそも強制終了しないようにすることです。

このメソッドを使用するとThread.setDefaultUncaughtExceptionHandler()アプリケーションを強制的に閉じる原因となっている例外をキャッチできます。

を使用してアプリケーションによって発生した例外をログに記録する例については、この質問UncaughtExceptionHandlerご覧ください。


1
手がかりをありがとう。次の質問は、UncaughtExceptionHandler.uncaughtExceptionがいつ呼び出されるかです。ユーザーが[強制終了]ボタンをクリックしなかった場合でも、UncaughtExceptionHandler.uncaughtExceptionが呼び出されますか?
ジョニー

3
@Johnnyアプリケーションが処理されない例外を発生させると、強制終了が発生します。UncaughtExceptionHandlerを使用する場合、アプリケーションはそのすべての例外を処理でき、ユーザーには[強制終了]ダイアログが表示されません。つまり、[強制終了]ダイアログが表示されたときにUncaughtExceptionHandlerが呼び出されます。ただし、アプリケーションがキャッチした予期しない例外の処理方法には注意が必要です。何も起こらなかったふりを続けて、明らかに危険です。
Dave Webb

説明ありがとう。UncaughtExceptionHandlerについてよく説明しています。しかし、強制終了後に自動再起動するアプリケーションを見てきました。例えば。ランチャー(良い例ではないかもしれませんが、サードパーティのアプリもこのように機能するのを見てきました)。アプリをこのように動作させたい場合はどうすればよいですか?ある種のシステム権限を使用する必要がありますか?
ジョニー

10

Crittercismまたはその他のエラー報告サービスを使用している場合、受け入れられた答えはほぼ正しいです。

final UncaughtExceptionHandler defaultHandler = Thread.getDefaultUncaughtExceptionHandler();
Thread.setDefaultUncaughtExceptionHandler(new UncaughtExceptionHandler() {
            public void uncaughtException(Thread thread, Throwable ex) {
              Intent launchIntent = new Intent(activity().getIntent());
              PendingIntent pending = PendingIntent.getActivity(CSApplication.getContext(), 0,
                    launchIntent, activity().getIntent().getFlags());
              getAlarmManager().set(AlarmManager.RTC, System.currentTimeMillis() + 2000, pending);
              defaultHandler.uncaughtException(thread, ex);
            }
});

2
public class ForceCloseExceptionHandalingActivity extends Activity {
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        setContentView(MyLayout());
        Thread.setDefaultUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() {
            @Override
            public void uncaughtException(Thread paramThread, Throwable paramThrowable) {
                myHandaling(paramThread, paramThrowable);
            }
        });
    }

    private ViewGroup MyLayout(){
        LinearLayout mainLayout = new LinearLayout(this);
        mainLayout.setOrientation(LinearLayout.VERTICAL);  
        Button btnHello =new Button(this);
        btnHello.setText("Show all button");
        btnHello.setOnClickListener(new OnClickListener() {         
            @Override
            public void onClick(View v) {                   
                setContentView(MyLayout2());            
            }
        });             
        mainLayout.addView(btnHello);       
        return mainLayout;
    }

    private ViewGroup MyLayout2(){
        LinearLayout mainLayout = new LinearLayout(this);
        mainLayout.setOrientation(LinearLayout.VERTICAL);  
        Button btnHello =new Button(this);
        btnHello.setText("I am a EEROR uncaughtException");
        btnHello.setOnClickListener(new OnClickListener() {         
            @Override
            public void onClick(View v) {                   
                Log.e("Alert","btn  uncaughtException::");
                Toast.makeText(ForceCloseExceptionHandalingActivity.this, "Alert uncaughtException222",Toast.LENGTH_LONG).show();
                View buttone = null;
                setContentView(buttone);            
            }
        });     
        Button btnHello2 =new Button(this);
        btnHello2.setText("I am a EEROR Try n catch");
        btnHello2.setOnClickListener(new OnClickListener() {            
            @Override
            public void onClick(View v) {   

                try{
                    View buttone = null;
                    setContentView(buttone);
                }
                catch (Exception e) {
                    Log.e("Alert","Try n catch:::");
                    Toast.makeText(ForceCloseExceptionHandalingActivity.this, "Alert Try n catch",Toast.LENGTH_LONG).show();
                    setContentView(MyLayout());
                }

            }
        });     
        mainLayout.addView(btnHello);
        mainLayout.addView(btnHello2);
        return mainLayout;
    }
    public void myHandaling(Thread paramThread, Throwable paramThrowable){
        Log.e("Alert","Lets See if it Works !!!" +"paramThread:::" +paramThread +"paramThrowable:::" +paramThrowable);
        Toast.makeText(ForceCloseExceptionHandalingActivity.this, "Alert uncaughtException111",Toast.LENGTH_LONG).show();
        Intent in =new Intent(ForceCloseExceptionHandalingActivity.this,com.satya.ForceCloseExceptionHandaling.ForceCloseExceptionHandalingActivity.class);
        startActivity(in);
        finish();
        android.os.Process.killProcess(android.os.Process.myPid()); 
    }
    @Override
    protected void onDestroy() {
        Log.e("Alert","onDestroy:::");
        Toast.makeText(ForceCloseExceptionHandalingActivity.this, "Alert onDestroy",Toast.LENGTH_LONG).show();
        super.onDestroy();  
    }

このコードは「Thread.setDefaultUncaughtExceptionHandler」を取得し、閉じられた後に呼び出します..
Satya

2

このクラスをパッケージに追加するだけです

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

アプリケーションまたはすべてのアクティビティクラスで、onCreate()メソッド内で次を呼び出すだけです。

Thread.setDefaultUncaughtExceptionHandler(new MyExceptionHandler(this,
            SplashScreenActivity.class));
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.