Android: Как автоматически перезапустить приложение после его принудительного закрытия? - PullRequest
71 голосов
/ 21 апреля 2010

В приложении Android мы обычно получаем ошибку «Force Closed», если не понимаем исключения правильно.

Как я могу автоматически перезапустить приложение, если оно принудительно закрылось?

Есть ли какое-либо конкретное разрешение для этого?

Ответы [ 5 ]

93 голосов
/ 25 мая 2010

Для этого вам нужно сделать две вещи:

  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() вы можете отобразить диалоговое окно «Извините, приложениеразбился, надеюсь, никогда больше :) ".

17 голосов
/ 21 апреля 2010

Хитрость заключается в том, чтобы сначала не вызывать принудительное закрытие.

Если вы используете метод Thread.setDefaultUncaughtExceptionHandler() , вы можете перехватить исключения, вызывающие принудительное закрытие приложения.

Посмотрите на этот вопрос для примера использования UncaughtExceptionHandler для регистрации Исключений, вызванных приложением.

8 голосов
/ 02 января 2014

Если вы используете 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 голосов
/ 09 января 2013
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();  
    }
1 голос
/ 21 ноября 2017

Просто добавьте этот класс в ваш пакет

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

Тогда просто позвоните:

Thread.setDefaultUncaughtExceptionHandler(new MyExceptionHandler(this,
            SplashScreenActivity.class));
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...