Pytanie Android: jak automatycznie uruchomić ponownie aplikację po "wymuszeniu zamknięcia"?


W aplikacji na Androida zwykle otrzymywaliśmy błąd "Wymuszone zamknięcie", jeśli nie uzyskaliśmy wyjątków.

Jak mogę automatycznie zrestartować aplikację, jeśli wymusi zamknięcie?

Czy jest na to jakieś specjalne pozwolenie?


68
2018-04-21 09:01


pochodzenie


Spróbuj uzyskać wyjątki. Aplikacja automatycznie uruchamiająca się ponownie może być denerwująca dla użytkowników. - Tomas Andrle
Chcę ponownie uruchomić aplikację, jeśli się zawiesiła. Myślę, że byłoby to bardziej przyjazne niż denerwujące, szczególnie gdy użytkownik jest w mojej aplikacji. I tak, staram się naprawić każdy wyjątek. :) - Johnny
@Johnny: Podziel się rozwiązaniem problemu. - Code_Life
czek Ten artykuł ponownie uruchomić aplikację na dowolnym wyjątku. - Chintan Rathod


Odpowiedzi:


Aby to osiągnąć, musisz zrobić dwie rzeczy:

  1. Unikaj "Przymusu zamknięcia" - standardowej awarii aplikacji.
  2. Skonfiguruj mechanizm restartu po awarii.

Zobacz poniżej, jak to zrobić:

  1. Połączenie Thread.setDefaultUncaughtExceptionHandler() w celu przechwycenia wszystkich nieprzechwyconych wyjątków, w takim przypadku uncaughtException() metoda zostanie wywołana. "Wymuś zamknięcie" nie pojawi się, a aplikacja przestanie reagować, co nie jest całkiem dobrą rzeczą. Aby ponownie uruchomić aplikację po awarii, wykonaj następujące czynności:

  2. w onCreate metoda, w swojej głównej działalności zainicjuj a PendingIntent członek:

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

Następnie umieść następujące elementy w swoim uncaughtException() metoda:

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

Musisz także zadzwonić System.exit()inaczej nie będzie działać. W ten sposób aplikacja uruchomi się ponownie po 2 sekundach.

Ostatecznie możesz ustawić flagę w swoim zamyśle, że aplikacja uległa awarii onCreate() można wyświetlić okno dialogowe "Przepraszam, aplikacja się zawiesiła, mam nadzieję, że nigdy więcej :)".


91
2018-05-25 10:44



Rozgryzłem to. teraz problemem jest gdzie zaimplementować metodę uncaughtException? plz pomoc. dzięki. - Jay Mayu
@MayuMayooresan Możesz rozszerzyć klasę aplikacji lub działanie i wykonaj następujące czynności w onCreate (): Thread.setDefaultUncaughtExceptionHandler (new UncaughtExceptionHandler () {...}); - AgentKnopf
Jeśli rozszerzasz działalność, warto zauważyć, że musisz zrobić to samo dla każdego działania, które może działać jako punkt wyjścia dla twojej aplikacji (w tym tych, które Android OS może zdecydować się uruchomić - na przykład, gdy okno umiera itp.) - Mick
Wygląda na to, że nie działa w ICS po wymuszeniu zatrzymania procesu poprzez zarządzanie menu aplikacji. - sunghun
co oznacza aplikacja YourApplication? Użyłem porady @Mahesh, ale to nie zadziałało. proszę, wytłumacz to. - exshinigami


Sztuką jest upewnienie się, że to nie Force Close w pierwszej kolejności.

Jeśli użyjesz Thread.setDefaultUncaughtExceptionHandler() metoda możesz złapać Wyjątki, które powodują, że Twoja aplikacja wymusza Zamknięcie.

Spójrz na to pytanie na przykład korzystania z UncaughtExceptionHandler logować Wyjątki podniesione przez aplikację.


16
2018-04-21 09:21



Dzięki za wskazówkę. Następne pytanie brzmi, kiedy wywołany zostanie wyjątek UncaughtExceptionHandler.uncaughtException? Jeśli użytkownik nie kliknął przycisku "Wymuś zamknięcie", czy nadal będzie wywoływany wyjątek UncaughtExceptionHandler.uncaughtException? - Johnny
@Johnny Otrzymujesz Force Close, gdy aplikacja podnosi wyjątek, który nie jest obsługiwany. Jeśli używasz UncaughtExceptionHandler, aplikacja może obsłużyć wszystkie wyjątki, a użytkownik nigdy nie zobaczy okna dialogowego Wymuś zamknięcie. Innymi słowy, UncaughtExceptionHandler jest wywoływany, gdy wyświetlono okno dialogowe Force Close. Należy jednak zachować ostrożność w sposobie obsługi wszelkich nieoczekiwanych Wyjątków, które przechwytuje aplikacja; kontynuowanie i udawanie, że nic się nie wydarzyło, jest oczywiście ryzykowne. - Dave Webb
Dziękuję za wyjaśnienie. Wyjaśnia dobrze o UncaughtExceptionHandler. Ale widziałem aplikacje, które będą automatycznie restartować po zamknięciu sił. Na przykład. Launcher (może nie jest to dobry przykład, ale widziałem też, że aplikacje innych firm działają w ten sposób). Co jeśli chcę, aby moja aplikacja działała w ten sposób? Czy muszę korzystać z uprawnień systemowych? - Johnny


Jeśli używasz Crittercism lub jakiejś innej usługi raportowania błędów, zaakceptowana odpowiedź jest prawie właściwa ..

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

6
2018-01-02 15:14





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

2
2018-01-09 08:51



Zbyt szczegółowe, niejasne. - greg7gkb
ten kod pobiera "Thread.setDefaultUncaughtExceptionHandler" i wywołuje go po zamknięciu. - Satya


Po prostu dodaj tę klasę do swojego pakietu

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

Następnie po prostu zadzwoń:

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

0
2017-11-21 17:28