8

我正在使用此代码来处理任何未捕获的异常,这可能会导致我的应用程序崩溃。吐露不出现在UnCaughtExceptionHandler

public class ExceptionHandler implements java.lang.Thread.UncaughtExceptionHandler { 
    private final Context myContext; 

    public ExceptionHandler(Context context) { 

     myContext = context; 
    } 

    public void uncaughtException(Thread thread, Throwable exception) { 

     Toast.makeText(myContext, 
       "The application has crashed, and a report is sent to the admin", 
       Toast.LENGTH_SHORT).show(); 
     StringWriter stackTrace = new StringWriter(); 
     exception.printStackTrace(new PrintWriter(stackTrace)); 
     System.err.println(stackTrace);// You can use LogCat too 
     Intent intent = new Intent(myContext, CrashActivity.class); 
     myContext.startActivity(intent); 
     Process.killProcess(Process.myPid()); 
     System.exit(10); 
    } 
} 

当我与一个已知的,但捕获的异常运行(只是为了测试),活动“CrashActivity”之称,但它必须来之前它的面包,还没有显示出来。

其实我只想显示吐司,然后调用myContext.finish();而不是去CrashActivity。但是,这在敬酒不可见。

我在哪里错了?

+2

我不是一个android程序员,但从阅读我已经完成,不敬酒必须在UI线程上调用?在这种情况下,你是否在UI线程上调用它?我猜你可能已经想到了这一点。 – 2012-07-23 09:24:02

+0

是的,你是对的..我不打电话给敬酒线程上的祝酒:( – 2012-07-23 09:32:15

回答

3

你大概从一个线程调用吐司而举杯应该从UI线程调用......

如果这没有帮助,请向我们提供了logcat的输出,所以我们可以看到什么样的错误你正在得到。

+0

是的我在错误的使用在不同的线程吐司。其实我看到这个应用程序,当应用程序崩溃它显示吐司上是否它实际上回忆起同样的活动,然后显示吐司? – 2012-07-23 09:31:50

7

找到这个问题,同时谷歌搜索完全相同的问题。 据我所知,只要存在应用程序上下文,就不需要从UI线程调用Toast.show()。 AFAIK:出现的问题如下:您尝试显示Toast,之后您的应用程序会立即关闭,这意味着您的Toast也会关闭。

用于问题的解决方案如下:

  • 从sepearate的线程中运行吐司
  • 应用程序的延时关机未捕获的异常处理程序。

我做的是以下几点:

Application::onCreate()

Thread.setDefaultUncaughtExceptionHandler(new UncaughtExceptionHandler() { 
    @Override 
    public void uncaughtException(Thread thread, Throwable ex) 
    { 
     new Thread() { 
      @Override 
      public void run() { 
       Looper.prepare(); 
       Toast.makeText(getApplicationContext(), "Application crashed", Toast.LENGTH_LONG).show(); 
       Looper.loop(); 
      } 
     }.start(); 

     try 
     { 
      Thread.sleep(4000); // Let the Toast display before app will get shutdown 
     } 
     catch (InterruptedException e) 
     { 
      // Ignored. 
     } 
    } 
}); 

它类同于ACRA的Toast通知如何工作(其实这就是我从提示) 。

+0

这正是我所需要的,因为我想要一个快速(临时)的方式来查看异常的一些细节。我发现我也必须在'catch'块之后的'System.exit()'调用中。这在上面是否缺失? – darrenp 2013-03-06 17:22:23

+0

Pjuh。好问题。我不会用'System.exit()'退出,但使用默认的异常处理程序和'_androidDefaultUncaughtExHandler.uncaughtException(thread,ex);'并使用_androidDefaultUncaughtExHandler = Thread.getDefaultUncaughtExceptionHandler()来设置它;' – GeneSys 2013-03-21 10:12:40

+1

有意义。默认的异常处理程序必须整理并调用'System.exit()'。 – darrenp 2013-03-25 16:32:57

3

从Android UncaughtExceptionHandler中调用System.exit(0)有助于应用程序从错误中恢复并重新启动上一次活动。恕我直言,用户体验得到显着改善。但是,这种方法需要在多个Android平台上进行尝试和测试。在GB和JB上试过这个。它运行良好。另外,我听说别人(我是Android的新手),在Android中不推荐调用System.exit(),但是..可以使用它作为Android应用程序崩溃的一个很好的恢复选项。

public void uncaughtException(Thread thread, Throwable ex) { 
     new Thread() { 
      @Override 
      public void run() { 
       Looper.prepare(); 
       Toast.makeText(YourActivity.this, "Application has Crashed. Recovering now.", Toast.LENGTH_LONG).show(); 
       /* Log relevant message/analytics from here. */ 
       System.exit(1); 
       Looper.loop(); 
      } 
     }.start(); 
    } 
+0

我怎么能避免重新启动应用程序时,我打电话System.exit()?我希望应用程序在发生崩溃时真正关闭,但我想捕获事件并通过电子邮件发送数据... – 2013-07-07 12:43:40

+0

'System.exit()'在大多数情况下会突然关闭应用程序,这通常是不是你想要的。无论您调用exit()还是不调用,该应用都会崩溃,因此不需要显式调用它。 – milosmns 2017-10-18 12:01:35