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
猜你喜欢
- 本文实例讲述了Java实现接口的枚举类。分享给大家供大家参考,具体如下:一 点睛枚举类也可以实现一个或多个接口。与普通类实现一个或多个接口完
- 双向顺序队列ArrayDeque和双向链式队列LinkedList,JDK已经包含,在此略。ArrayDeque包括顺序栈和顺序队列,Lin
- 目录样例代码在讲 Flutter 的盒子模型前,先看看HTML 中的盒子模型。如下图所示,一个页面元素包括了与父级容器的外边距(margin
- 一、百度百科Sentinel 是面向分布式服务架构的高可用流量防护组件,主要以流量为切入点,从限流、流量整形、熔断降级、系统负载保护、热点防
- 本文实例讲述了C#中HttpWebRequest的用法。分享给大家供大家参考。具体如下:HttpWebRequest类主要利用HTTP 协议
- 马上过年了。过年微信红包很火,最近有个项目也要做抢红包,于是写了个红包的生成算法。红包生成算法的需求预先生成所有的红包还是一个请求随机生成一
- 协议做如下规定:规定数据协议:序列号 长度 状态字 数据长度 数据1 &n
- 本文首发于https://blog.chens.life/2020-2-idea.html参考链接亲测试以下版本成功激活附激活教程。idea
- 什么是异步?为什么要用它?异步编程提供了一个非阻塞的,事件驱动的编程模型。 这种编程模型利用系统中多核执行任务来提供并行,因此提供了应用的吞
- 本文实例讲述了java实现的简单猜数字游戏代码。分享给大家供大家参考。具体代码如下:import java.util.InputMismat
- 1.ArrayList 是基数组结构的,需要连续的内存空间从构造函数可以看出,ArrayList内部用一个Object数组来保存数据。对于无
- jdk8之前 一、java.lang.Systemlong times = System.currentTimeMillis();
- 您已经看到很多包含视频内容的应用程序,比如带有视频教程的食谱应用程序、电影应用程序和体育相关的应用程序。您是否想知道如何将视频内容添加到您的
- 在观察者模式中有2个要素:一个是被观察对象,另一个是观察者。但被观察对象的状态发生改变会通知观察者。举例:把订阅报纸的人看作是观察者,把报纸
- feign传输List的坑无法直接传输List错误方法1@RequestMapping(value = "/stat/mercha
- mport java.text.DecimalFormat; DecimalFormat &nb
- 1、前言当提及如何终止一个线程时,部分读者通常立马想到的方法肯定是stop(),但是stop()方法并不被推荐使用(很多规范中是禁止使用的)
- [LeetCode] 205. Isomorphic Strings 同构字符串Given two strings s
- 1 自定义类加载器自定义类加载器的代码很简单,只需要继承ClassLoader类,覆写findClass方法即可其默认实现是会抛出一个异常:
- 概述:App几乎都离不开与服务器的交互,本文主要讲解了flutter网络请求三种方式 flutter自带的HttpClient、 第三方库h