2012-01-29 11 views
6

W mojej klasie aplikacji próbuję złapać siłę blisko, zanim się to stanie, więc mogę ją zalogować, a następnie ponownie ją wysłać, aby android mógł sobie z tym poradzić. Robię to, ponieważ niektórzy użytkownicy nie zgłaszają zamknięcia sił.Rethrow UncaughtExceptionHandler Wyjątek po zalogowaniu się

Rozwijam się w czasie zaćmienia, a zaćmienie nie pozwala mi na powtórzenie wyjątku. Pokazuje komunikat "Nieobsługiwany typ wyjątku Throwable: Surround with try/catch". Jak mogę ponownie rzucić wyjątek?

public class MainApplication extends Application 
{ 
    @Override 
    public void onCreate() 
    { 
    super.onCreate(); 

    try 
    { 
     //Log exception before app force closes 
     Thread.currentThread().setUncaughtExceptionHandler(new UncaughtExceptionHandler() { 
      @Override 
      public void uncaughtException(Thread thread, Throwable ex) { 
       AnalyticsUtils.getInstance(MainApplication.this).trackEvent(
         "Errors",      // Category 
         "MainActivity",     // Action 
         "Force Close: "+ex.toString(), // Label 
         0);        // Value 
       AnalyticsUtils.getInstance(MainApplication.this).dispatch(); 

       Toast.makeText(MainApplication.this, "Snap! Something broke. Please report the Force Close so I can fix it.", Toast.LENGTH_LONG); 

       //rethrow the Exception so user can report it 
       //throw ex; //<-- **eclipse is showing an error to surround with try/catch** 
      } 
     }); 

    } catch (Exception e) 
    { 
     e.printStackTrace(); 
    } 
} 

}

Odpowiedz

12

Przepraszamy, nie Android ekspert - ale wygląda na to, że nie można rzucać ex ponieważ podpis metoda „nieważne uncaughtException (wątek, Throwable)” nie deklaruje, że „rzuca” byle co.

Zakładając, że przesłoniłeś interfejs API i (a) nie możesz zmodyfikować tego podpisu i (b) nie chcesz, ponieważ wyrzucisz go z kontekstu, możesz zamiast tego użyć wzoru dekoratora i w zasadzie podklasuj domyślną implementację UncaughtExceptionHandler, aby zarejestrować wiadomość, a następnie pozwolić jej kontynuować przetwarzanie w zwykły sposób?

Edit: niesprawdzone, ale może to wyglądać trochę jak:

final UncaughtExceptionHandler subclass = Thread.currentThread().getUncaughtExceptionHandler(); 
    Thread.currentThread().setUncaughtExceptionHandler(new UncaughtExceptionHandler() { 
     @Override 
     public void uncaughtException(Thread thread, Throwable ex) { 
      // your code 
      AnalyticsUtils.getInstance(MainApplication.this).trackEvent(
        "Errors",      // Category 
        "MainActivity",     // Action 
        "Force Close: "+ex.toString(), // Label 
        0);        // Value 
      AnalyticsUtils.getInstance(MainApplication.this).dispatch(); 
      Toast.makeText(MainApplication.this, "Snap! Something broke. Please report the Force Close so I can fix it.", Toast.LENGTH_LONG).show(); 

      // carry on with prior flow 
      subclass.uncaughtException(thread, ex); 
     } 
    }); 
+0

Hmm Myślę, że masz rację. Nie znam schematu dekoratora, czy mógłbyś pokazać kod, który pokazałby mi, jak mogę to zrobić? –

+0

Tak, zadziałało! Dzięki, Capn Sparrow. (Uwaga: toast się nie pokazuje.) –

+0

Trochę późno, ale jak już użyłem rozwiązania Capn Sparrow, powinienem zaznaczyć, że toast nie jest wyświetlany, ponieważ teraz jest .show() na końcu wywołania makeText. To często mnie spotyka. – AJ87uk

0

Nie jestem dokładnie pewien, czy to, co chcesz, ale można dodać finally klauzulę, że będzie działał po albo sukces try lub obsługiwane catch:

try { 
    //your code 
} catch (Exception e) { 
    //print stack trace 
} finally { 
    //Log 
} 
+0

Nie do końca to, czego szukam, ponieważ chciałbym "złapać wszystko", które będzie rejestrować każdy wyjątek, zanim zamknie moją aplikację. Używam try/catch, ale na wszelki wypadek, gdy coś stanie się nieprzytomne. –

0

myślę Poniższy kod powinien działać. Wykonywanie kodu obsługi za pomocą nowego wątku umożliwia aplikacji wyświetlanie alertów/tostów i wykonywanie innych operacji.

Możesz także spróbować wywołać System.exit(0) tuż przed zakończeniem run(). Powoduje to ponowne uruchomienie ostatniej czynności.

Sprawdziłem to zarówno na Ginger Bread, jak i Jelly Bean.

final UncaughtExceptionHandler subclass = Thread.currentThread().getUncaughtExceptionHandler(); 
    Thread.currentThread().setUncaughtExceptionHandler(new UncaughtExceptionHandler() { 
     @Override 
     public void uncaughtException(Thread thread, Throwable ex) { 
      new Thread() { 
       @Override 
       public void run() { 
        Looper.prepare(); 
        // your code 
        AnalyticsUtils.getInstance(MainApplication.this).trackEvent(
          "Errors",      // Category 
          "MainActivity",     // Action 
          "Force Close: "+ex.toString(), // Label 
          0);        // Value 
        AnalyticsUtils.getInstance(MainApplication.this).dispatch(); 
        Toast.makeText(MainApplication.this, "Snap! Something broke. Please report the Force Close so I can fix it.", Toast.LENGTH_LONG); 

        Looper.loop(); 
       } 
      }.start(); 
     } 
    }); 
Powiązane problemy