Android Java try catch 失效问题及解决

作者:吃饱很舒服 时间:2023-06-17 17:07:33 

参考:

  • How to catch an Exception from a thread

  • Is there a way to make Runnable's run() throw an exception?

  • Java捕获线程异常的几种方式

如果你在 异常抛出处 的 外层函数 中添加了 try catch 不生效的话, 就试试下面的办法吧.

解决办法

方法一

如果在 异常抛出处 或 外层调用函数中 使用了 Runnable run 函数, try catch 需要添在 run 函数里面, 如下:

new Thread(new Runnable() {
               @Override
               public void run() {
                   try {
                       throw new IllegalArgumentException("test exception");
                   } catch (Exception e) {
                       e.printStackTrace();
                   }
               }
           }).start();

如果使用的是第三方库, 无法捕获 Runnable run 函数中的异常时, 则可在 Runnable 之前添加如下代码解决(需注意: 此方法在 Android 中子线程可用, 主线程仍会 crash):

// 在调用第三方库前先执行下面代码
Thread.setDefaultUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() {
               @Override
               public void uncaughtException(Thread t, Throwable e) {
                    // 这里就可以捕获到第三方库的异常了  
               }
           });

// 假如这里是一个第三方库抛出异常的地方
new Thread(new Runnable() {
               @Override
               public void run() {
                   // 子线程 -> 抛出异常
                   throw Exception("unknown exception");
               }
           }).start();

在 Android 中, 如果无法捕获 Runnable run 函数中的异常, 并且是在主线程调用, 就只能想办法避免 crash 了. 

比如我是在调用 show 函数之前有网络请求, 网络请求成功后, 此页面已不在前台, 才会导致 crash; 可以在网络请求成功后, 判断此页面是否在前台展示, 再执行相关操作.

事情起因

新版上线后, 出现了这个 crash. 经排查, 发现 crash 是从第三方库中抛出的, 位置如下: 

2021-12-23 17:39:57.408 3535-3535/com.podbean.app.podcast E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.podbean.app.podcast, PID: 3535
    java.lang.IllegalArgumentException: the view is not showing in the window!
        at com.app.hubert.guide.util.ViewUtils.getLocationInView(ViewUtils.java:47)
        at com.app.hubert.guide.model.HighlightView.fetchLocation(HighlightView.java:77)
        at com.app.hubert.guide.model.HighlightView.getRectF(HighlightView.java:67)
        at com.app.hubert.guide.model.RelativeGuide.getMarginInfo(RelativeGuide.java:90)
        at com.app.hubert.guide.model.RelativeGuide.getGuideLayout(RelativeGuide.java:76)
        at com.app.hubert.guide.core.GuideLayout.addCustomToLayout(GuideLayout.java:227)
        at com.app.hubert.guide.core.GuideLayout.onAttachedToWindow(GuideLayout.java:185)
        at android.view.View.dispatchAttachedToWindow(View.java:20479)
        at android.view.ViewGroup.dispatchAttachedToWindow(ViewGroup.java:3489)
        at android.view.ViewGroup.addViewInner(ViewGroup.java:5278)
        at android.view.ViewGroup.addView(ViewGroup.java:5064)
        at android.view.ViewGroup.addView(ViewGroup.java:5036)
        at com.app.hubert.guide.core.Controller.showGuidePage(Controller.java:175)
        at com.app.hubert.guide.core.Controller.access$200(Controller.java:39)
        at com.app.hubert.guide.core.Controller$1.run(Controller.java:118)
        at android.os.Handler.handleCallback(Handler.java:938)
        at android.os.Handler.dispatchMessage(Handler.java:99)
        at android.os.Looper.loop(Looper.java:223)
        at android.app.ActivityThread.main(ActivityThread.java:7664)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:592)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:947)

根据 log 信息, 最终我找到了这里

// ViewUitls.java
public static Rect getLocationInView(View parent, View child) {
   ...
   if (tmp == null) {
       // 异常抛出位置
       throw new IllegalArgumentException("the view is not showing in the window!");
           }
   ...
}

// Controller.java
public void show() {
       ...
       // 使用 Runnable run 位置
       mParentView.post(new Runnable() {
           @Override
           public void run() {
               ...
               // showGuidePage 会调用到异常抛出的位置
               showGuidePage();
               ...
           }
       });
   }

发现在 show 函数中, 有关键代码 mParentView.post(runnable), 此时, 异常就是在 run 函数中调用的 showGuidePage 中抛出的, 并且这个异常在主线程中, 主线程就会停止掉, 就会 crash!

来源:https://blog.csdn.net/HongHuaZu/article/details/122111081

标签:Android,Java,try,catch
0
投稿

猜你喜欢

  • 记一次公司JVM堆溢出抽丝剥茧定位的过程解析

    2023-11-09 13:11:24
  • Android Monkey压力测试详细介绍

    2021-10-24 08:02:37
  • Java多态和实现接口的类的对象赋值给接口引用的方法(推荐)

    2023-11-26 11:59:41
  • MyBatis全局映射文件实现原理解析

    2021-06-21 17:01:29
  • 以一个着色游戏展开讲解Android中区域图像填色的方法

    2023-02-04 10:02:51
  • eclipse 联想功能设置技巧

    2023-03-18 04:11:39
  • c#实现的操作oracle通用类

    2022-01-31 15:08:37
  • C#使用struct直接转换下位机数据的示例代码

    2023-06-07 01:49:01
  • Java 单例模式的实现资料整理

    2022-05-29 21:27:33
  • C# 通过同步和异步实现优化做早餐的时间

    2022-10-27 23:09:27
  • C语言多种获取字符串长度的方法

    2021-07-01 16:30:29
  • unity 文件流读取图片与www读取图片的区别介绍

    2023-08-30 09:10:37
  • 在C#中捕获内存不足异常

    2021-07-14 11:50:46
  • MyBatis 中 ${}和 #{}的正确使用方法(千万不要乱用)

    2023-11-29 05:02:37
  • java开发_图片截取工具实现原理

    2023-10-23 22:52:06
  • SpringBoot异步调用方法实现场景代码实例

    2023-10-23 14:14:23
  • Android自定义View实现通讯录字母索引(仿微信通讯录)

    2023-05-14 04:34:22
  • Android高级图片滚动控件实现3D版图片轮播器

    2022-03-14 23:36:30
  • java反射获取和调用方法

    2021-11-23 11:05:02
  • hadoop是什么语言

    2021-06-18 07:02:38
  • asp之家 软件编程 m.aspxhome.com