Android 避免在运行时异常的情况下使处理程序线程崩溃?

Android 避免在运行时异常的情况下使处理程序线程崩溃?,android,android-handler,Android,Android Handler,我有一个处理程序(线程),我在其上发布可运行程序。如果Runnable错误地抛出RuntimeException,则整个应用程序进程将崩溃。默认情况下,这听起来很合理,但我希望捕获此类运行时异常,记录错误,然后继续运行。不过,我很难做到这一点。我想到了以下几种选择: 子类Looper和重写loop(),其中包含调用已发布Runnables的run()方法的代码。这不起作用,因为活套是最终版本 子类HandlerThread并重写调用Looper.loop()的run方法。如果出现运行时异常,请再

我有一个处理程序(线程),我在其上发布可运行程序。如果Runnable错误地抛出RuntimeException,则整个应用程序进程将崩溃。默认情况下,这听起来很合理,但我希望捕获此类运行时异常,记录错误,然后继续运行。不过,我很难做到这一点。我想到了以下几种选择:

  • 子类
    Looper
    和重写
    loop()
    ,其中包含调用已发布Runnables的
    run()
    方法的代码。这不起作用,因为
    活套
    是最终版本
  • 子类
    HandlerThread
    并重写调用
    Looper.loop()
    的run方法。如果出现运行时异常,请再次调用
    super.run()
    ,以此类推。这不起作用,因为“每个线程只能创建一个活套”
  • 在每个可运行类中,包括运行时异常的try-catch。这会起作用,但很烦人,因为我有很多不同的可运行类。此外,如果runnable错误地忘记包含try-catch,则不会保护处理程序线程
  • 在一个完美的世界中,Looper将有一个名为
    registerExceptionHandler(ExceptionHandler)
    的成员方法,然后在出现异常时调用
    ExceptionHandler


    有人有更好的建议吗

    尝试此自定义处理程序:

    class H extends Handler {
        public H(Looper looper) {
            super(looper);
        }
    
        @Override
        public void dispatchMessage(Message msg) {
            // catch any Exception
            try {
                super.dispatchMessage(msg);
            } catch (Exception e) {
                Log.d(TAG, "dispatchMessage " + e.getMessage());
            }
        }
    }
    
    测试代码:

    HandlerThread ht = new HandlerThread("hthread");
    ht.start();
    Handler h = new H(ht.getLooper());
    
    Runnable r = new Runnable() {
        @Override
        public void run() {
            throw new RuntimeException("testing exception");
        }
    };
    h.post(r);
    h.post(r);
    

    在一个完美的世界中,
    DefaultExceptionHandler
    在整个应用程序中对我来说就像一个魅力。当它导致未处理的异常时,它会触发

    名为的库。您只需要在应用程序类中注册这些DefaultHandlerException类的广播

    片段:

     public class Portfolio extends Application {
     static Portfolio portfolio;
     public void onCreate() {
        super.onCreate();
        portfolio = this;
        ExceptionHandler.register(portfolio);// registering for unhandled Exceptions
       }
     }
    

    您可以使用这些工具执行各种任务,例如将日志堆栈跟踪上载到服务器,或者使用未处理的堆栈跟踪以崩溃报告的形式发送应用程序崩溃的邮件。

    最简单的方法似乎是从Runnable派生:

    public abstract class RunnableBase implements Runnable
    {
        public final void run()
        {
            try {
                runInternal();
            }
            catch(Exception e) {
                // handle the exception
            }
        }
    
        // to be implemented by concrete subclasses
        protected abstract void runInternal();
    }
    

    将runnable代码放入try-catch块并捕获异常。所以runnable不会抛出捕获的异常。您可以根据需要在catch块中管理异常。对,我认为这就是我所说的选项3,我认为这是一种解决方法。问题是我有几个可运行的类,希望避免在每个类中添加这样的代码。是的,这就是设置和启动HandlerThread的方式。如果您执行类似于
    ht.post(new RuntimeGeneratingRunnable)
    的操作,应用程序进程将崩溃。你知道如何避免吗?不要使用Runnables,使用sendMessage和Handler.CallbackRight,那样就行了。我必须转换为使用消息而不是Runnables,所以我想我更喜欢向所有Runnables添加try-catch。。。如果没有更好的方法。或者,您也可以使用Runnables,但您需要具有重写的dispatchMessage方法的自定义处理程序:尝试{super.etcplese更新您的答案以符合问题创建者的要求。:)这不完全是我要求的,但显然很有用。我的直接想法是,“恢复”为时已晚处理程序线程,但我不确定。我将进行调查并让您知道。感谢您的响应!我已经查看了它。我不知道存在DefaultExceptionHandler;这肯定很有趣,值得一读。对于这种特殊情况,这意味着队列中任何挂起的可运行程序都将丢失,处理程序线程必须被删除重新启动等,所以不是很合适,不幸的是:-(。