2010-04-21 11 views
65

In einer Android-Anwendung haben wir normalerweise den "Force Closed" -Fehler, wenn wir die Ausnahmen nicht richtig gemacht haben.Android: Wie wird die Anwendung automatisch neu gestartet, nachdem sie "zwangsweise geschlossen" wurde?

Wie kann ich meine Anwendung automatisch neu starten, wenn sie geschlossen wird?

Wird dafür eine bestimmte Berechtigung verwendet?

+4

Versuchen Sie, die Ausnahmen richtig zu bekommen.Eine Anwendung, die sich automatisch neu startet, kann für Benutzer lästig sein. –

+10

Ich möchte nur meine Anwendung neu starten, wenn es abgestürzt ist. Ich denke, es wäre freundlicher als lästig, besonders wenn der Benutzer in meiner Anwendung ist. Und ja, ich versuche, jede Ausnahme richtig zu machen. :) – Johnny

+2

@Johnny: Bitte teilen Sie die Lösung für Ihr Problem. –

Antwort

90

Um diese zwei Dinge zu erreichen tun:

  1. Vermeiden Sie die „Force close“ - Standardmethode der Anwendung zum Absturz bringen.
  2. Richten Sie einen Neustartmechanismus ein, wenn der Absturz trotzdem auftritt.

Siehe unten, wie diese zu tun:

  1. Anruf Thread.setDefaultUncaughtExceptionHandler() um alle abgefangene Ausnahme zu fangen, wobei in diesem Fall uncaughtException() Methode aufgerufen wird. "Schließen erzwingen" wird nicht angezeigt und die Anwendung reagiert nicht, was nicht sehr gut ist. Um Ihre Anwendung neu zu starten, wenn es abgestürzt Sie Folgendes tun sollten:

  2. Im onCreate Methode initialisieren in Ihrer Haupttätigkeit ein PendingIntent Mitglied:

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

dann in den folgenden setzen Ihre uncaughtException() Methode:

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

Sie auch System.exit() nennen müssen , sonst wird nicht funktionieren. Auf diese Weise wird Ihre Anwendung nach 2 Sekunden neu gestartet.

Schließlich können Sie ein Flag in Ihrer Absicht setzen, dass die Anwendung abgestürzt ist und in Ihrer onCreate() Methode können Sie einen Dialog anzeigen "Es tut mir leid, die Anwendung abgestürzt, hoffe nie wieder :)".

+3

Ich habe das herausgefunden. Jetzt ist das Problem, wo uncaughtException Methode implementieren? PLZ Hilfe. Vielen Dank. –

+1

@MayuMayooresan Sie können entweder die Anwendungsklasse oder die Aktivität erweitern und in onCreate() folgende Schritte ausführen: Thread.setDefaultUncaughtExceptionHandler (new UncaughtExceptionHandler() {...}); – AgentKnopf

+1

Wenn Sie die Aktivität erweitern, sollten Sie das Gleiche für jede Aktivität tun, die als Einstiegspunkt für Ihre Anwendung dienen kann (einschließlich derer, die Android OS möglicherweise startet - zum Beispiel wenn ein Fenster stirbt usw.) – Mick

15

Der Trick ist, stellen Sie sicher, dass es Force Close nicht an erster Stelle.

Wenn Sie the Thread.setDefaultUncaughtExceptionHandler() method verwenden, können Sie die Ausnahmen abfangen, die Ihre Anwendung zum Schließen erzwingen.

Werfen Sie einen Blick auf at this question für ein Beispiel für die Verwendung eines UncaughtExceptionHandler, um die Ausnahmen von einer Anwendung ausgelöst protokollieren.

+1

Danke für den Hinweis. Eine folgende Frage ist, wann würde die UncaughtExceptionHandler.uncaughtException aufgerufen werden? Wenn der Benutzer nicht auf die Schaltfläche "Schließen erzwingen" geklickt hat, wird die UncaughtExceptionHandler.uncaughtException trotzdem aufgerufen? – Johnny

+3

@Johnny Sie erhalten einen erzwungenen Abschluss, wenn die Anwendung eine Ausnahme auslöst, die nicht behandelt wird. Wenn Sie einen UncaughtExceptionHandler verwenden, kann Ihre Anwendung alle ihre Exceptions behandeln und der Benutzer wird nie den Force Close-Dialog sehen. Mit anderen Worten, der UncaughtExceptionHandler wird aufgerufen, wenn der Force Close-Dialog angezeigt wurde. Sie sollten jedoch vorsichtig sein, wie Sie mit unerwarteten Ausnahmen umgehen, die Ihre Anwendung abfängt. weitermachen und so tun, als sei nichts passiert, ist offensichtlich riskant. –

+0

Danke für die Erklärung. Es erklärt gut über den UncaughtExceptionHandler. Aber ich habe Anwendungen gesehen, die nach dem Schließen der Kraft automatisch neu gestartet werden. Z.B. Launcher (vielleicht kein gutes Beispiel, aber Apps von Drittanbietern funktionieren auch so). Was ist, wenn ich möchte, dass meine App so funktioniert? Muss ich Systemberechtigungen verwenden? – Johnny

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

Übermäßig wortreich, unklar. – greg7gkb

+0

Diesen Code erhalten Sie den "Thread.setDefaultUncaughtExceptionHandler" und rufen Sie auf, nachdem es geschlossen wurde .. – Satya

6

Wenn Sie Crittercism oder einen anderen Fehlermeldung Service, akzeptierte Antwort verwenden ist fast richtig ..

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

einfach diese Klasse in Ihrem Paket hinzufügen

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

Dann rufen Sie einfach an:

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