崩溃bug日志总结1
目录介绍
- 1.1 java.lang.UnsatisfiedLinkError找不到so库异常
- 1.2 java.lang.IllegalStateException非法状态异常
- 1.3 android.content.res.Resources$NotFoundException
- 1.4 java.lang.IllegalArgumentException参数不匹配异常
- 1.5 IllegalStateException:Can't compress a recycled bitmap
- 1.6 java.lang.NullPointerException空指针异常
- 1.7 android.view.WindowManager$BadTokenException异常
- 1.8 java.lang.ClassCastException类转化异常
- 1.9 1.9 Toast运行在子线程问题,handler问题
好消息
- 博客笔记大汇总【16年3月到至今】,包括Java基础及深入知识点,Android技术博客,Python学习笔记等等,还包括平时开发中遇到的bug汇总,当然也在工作之余收集了大量的面试题,长期更新维护并且修正,持续完善……开源的文件是markdown格式的!同时也开源了生活博客,从12年起,积累共计47篇[近20万字],转载请注明出处,谢谢!
- 链接地址:https://github.com/yangchong211/YCBlogs
- 如果觉得好,可以star一下,谢谢!当然也欢迎提出建议,万事起于忽微,量变引起质变!
1.1 java.lang.UnsatisfiedLinkError
- A.详细崩溃日志信息
# main(1)
java.lang.UnsatisfiedLinkError
dalvik.system.PathClassLoader[DexPathList[[zip file "/data/app/com.paidian.hwmc-1/base.apk", dex file "/data/app/com.paidian.hwmc-1/base.apk"],nativeLibraryDirectories=[/data/app/com.paidian.hwmc-1/lib/arm64, /data/app/com.paidian.hwmc-1/base.apk!/lib/arm64-v8a, /vendor/lib64, /system/lib64]]] couldn't find "libijkffmpeg.so"
- B.查看崩溃类信息
- 这个异常类的大意是:如果Java虚拟机找不到声明为
本机的方法的适当本机语言定义,则引发。
public class UnsatisfiedLinkError extends LinkageError {
private static final long serialVersionUID = -4019343241616879428L; public UnsatisfiedLinkError() {
super();
} public UnsatisfiedLinkError(String s) {
super(s);
}
}
- 这个异常类的大意是:如果Java虚拟机找不到声明为
- C.项目中异常分析
- 根据实际项目可知,当准备播放视频时,找不到libijkffmpeg.so这个库,导致直接崩溃。
- D.引发崩溃日志的流程分析
- F.解决办法
- 报这个错误通常是so库加载失败,或者找不到准备执行的JNI方法:
- 1.建议检查so在安装的过程中是否丢失,没有放入指定的目录下;
- 2.调用loadLibrary时检查是否调用了正确的so文件名,并对其进行捕获,进行相应的处理,防止程序发生崩溃;
- 3.检查下so的架构是否跟设备架构一至(如在64-bit架构下调用32-bit的so)。
- 代码展示
ndk {
//根据需要 自行选择添加的对应cpu类型的.so库。
//abiFilters 'armeabi', 'armeabi-v7a', 'arm64-v8a', 'x86', 'mips'
abiFilters 'armeabi-v7a'
} dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
//这两个是必须要加的,其它的可供选择
compile 'tv.danmaku.ijk.media:ijkplayer-java:0.8.4'
compile 'tv.danmaku.ijk.media:ijkplayer-armv7a:0.8.4'
//其他库文件
//compile 'tv.danmaku.ijk.media:ijkplayer-armv5:0.8.8'
//compile 'tv.danmaku.ijk.media:ijkplayer-arm64:0.8.8'
//compile 'tv.danmaku.ijk.media:ijkplayer-x86:0.8.8'
//compile 'tv.danmaku.ijk.media:ijkplayer-x86_64:0.8.8'
}
- 报这个错误通常是so库加载失败,或者找不到准备执行的JNI方法:
1.2 java.lang.IllegalStateException非法状态异常
- A.详细崩溃日志信息
- onSaveInstanceState方法是在该Activity即将被销毁前调用,来保存Activity数据的,如果在保存玩状态后 再给它添加Fragment就会出错。
IllegalStateException: Can not perform this action after onSaveInstanceState:
- B.查看崩溃类信息
- 在非法或不适当的时间调用方法的信号。换句话说,Java环境或Java应用程序没有处于请求操作的适当状态。
public class IllegalStateException extends RuntimeException {
public IllegalStateException() {
super();
} public IllegalStateException(String s) {
super(s);
} public IllegalStateException(String message, Throwable cause) {
super(message, cause);
} public IllegalStateException(Throwable cause) {
super(cause);
} static final long serialVersionUID = -1848914673093119416L;
}
- C.项目中异常分析
- 分析
- D.引发崩溃日志的流程分析
- F.解决办法
- 解决办法就是把commit()方法替换成 commitAllowingStateLoss()
- G.其他延申
- 错误类型大致为以下几种:
java.lang.IllegalStateException:Can't change tag of fragment d{e183845 #0 d{e183845}}: was d{e183845} now d{e183845 #0 d{e183845}}
java.lang.IllegalStateException:Expected BEGIN_ARRAY but was BEGIN_OBJECT at line 1 column 37 path $.data
- 第一种:我在显示fragment的代码中使用了:fragment.show(getSupportFragmentManager, fragment.toString());而这里是因为两次toString()结果不同,导致不同的tag指向的是同一个fragment。获取fragment的tag的正确方法应该是使用其提供的fragment.getTag()方法。
- 第二种:该异常是由于服务器错误返回的JSON字符串和服务器正常下时返回的JSON字符串结构不同,导致利用Gson解析的时候报了一个异常:本该去解析集合却强制去解析对象所致.解决办法:在使用Gson解析JSON时try cash一下,不报错按照正常逻辑继续解析,报异常则处理为请求失败逻辑即可.
1.3 android.content.res.Resources$NotFoundException
- A.详细崩溃日志信息
- Android资源不是可绘制的(颜色或路径)
Resource is not a Drawable (color or path): TypedValue{t=0x2/d=0x7f040151 a=2}
android.view.LayoutInflater.createView(LayoutInflater.java:620)
- B.查看崩溃类信息
- 当找不到请求的资源时,资源API将引发此异常。
public static class NotFoundException extends RuntimeException {
public NotFoundException() {
} public NotFoundException(String name) {
super(name);
} public NotFoundException(String name, Exception cause) {
super(name, cause);
}
}
- C.项目中异常分析
- 由于将图片资源拷贝到了drawable-land-xhdpi目录下,本来应该拷贝到drawable-xhdpi目录下。
- D.引发崩溃日志的流程分析
- F.解决办法
- 1.引用的资源ID 是否能匹配到R.java文件中定义的资源;
- 2.是否因为缓存等原因导致编译APK时未把资源文件打包进去,可以把APK反编译检查下;
- 3.是否使用了一个错误的类型来引用了某个资源或者配置资源时存在错误;
- 4.是否将Int等整型变量作为了参数传给了View.setText调用,这种情况下该整型变量将被认为是一个资源ID号去资源列表中查找对应的资源,导致找不到对应资源错误;解决方法是做类型转换View.setText(String.valueOf(Int id))。
1.4 java.lang.IllegalArgumentException参数不匹配异常
- A.详细崩溃日志信息
- B.查看崩溃类信息
- 参数不匹配异常,通常由于传递了不正确的参数导致。
public class IllegalArgumentException extends RuntimeException {
public IllegalArgumentException() {
super();
} public IllegalArgumentException(String s) {
super(s);
} public IllegalArgumentException(String message, Throwable cause) {
super(message, cause);
} public IllegalArgumentException(Throwable cause) {
super(cause);
} private static final long serialVersionUID = -5365630128856068164L;
}
- C.项目中异常分析
- D.引发崩溃日志的流程分析
- F.解决办法
- G.常见的出现场景
- Activity、Service状态异常;
- 非法URL;
- UI线程操作。
- Fragment中嵌套了子Fragment,Fragment被销毁,而内部Fragment未被销毁,所以导致再次加载时重复,在onDestroyView() 中将内部Fragment销毁即可
- 在请求网络的回调中使用了glide.into(view),view已经被销毁会导致该错误
1.5 IllegalStateException:Can't compress a recycled bitmap
- A.详细崩溃日志信息
- 无法压缩回收位图
Can't compress a recycled bitmap
com.paidian.hwmc.utils.i.a(FileUtils.java:75)
- B.查看崩溃类信息
- 如果位图已被回收,则希望抛出异常的方法将调用此值。知道了崩溃的具体位置,就该分析具体的原因呢!
public boolean compress(CompressFormat format, int quality, OutputStream stream) {
checkRecycled("Can't compress a recycled bitmap");
//省略代码
return result;
} //如果位图已被回收,则希望抛出异常的方法将调用此值。
private void checkRecycled(String errorMessage) {
if (mRecycled) {
throw new IllegalStateException(errorMessage);
}
}
- C.项目中异常分析
- 使用了已经被释放过内存的对象。对于Bitmap:Bitmap bitmap=一个bitmap对象。使用过程中调用bitmap.recycle(),之后再使用bitmap就会报错。
- D.引发崩溃日志的流程分析
- bitmap.recycle()解释如下所示,释放与此位图关联的本机对象,并清除对像素数据的引用。这将不会同步释放像素数据;它只允许在没有其他引用的情况下对其进行垃圾收集。位图被标记为“死”,这意味着如果调用getPixels()或setPixels(),它将抛出异常,而不会绘制任何内容。此操作不能反转,因此只有在确定没有进一步使用位图的情况下才应调用该操作。这是一个高级调用,通常不需要调用,因为当没有对此位图的引用时,普通GC进程将释放此内存。
Free the native object associated with this bitmap, and clear the reference to the pixel data
- F.解决办法
- 第一种:在使用bitmap前增加判断,if (mBitmap.isRecycled()) return null;
- 第二种:
1.6 java.lang.NullPointerException空指针异常
- A.详细崩溃日志信息
Please call the AutoSizeConfig#init() first
com.paidian.hwmc.base.BaseApplication.initAutoSizeConfig(BaseApplication.java:386)
- B.查看崩溃类信息
- 空指针异常,也是十分常见的一个异常
public class NullPointerException extends RuntimeException {
private static final long serialVersionUID = 5162710183389028792L;
public NullPointerException() {
super();
}
public NullPointerException(String s) {
super(s);
}
}
- C.项目中异常分析
- 空指针发生场景较多,是指某一个对象报null,这个使用去使用它的话就i会报该异常。
- D.引发崩溃日志的流程分析
- F.解决办法
- 空指针最为常见,也最容易规避,使用的时候一定要进行null check,采取不信任原则:
- 1.方法形参要判空后才使用;
- 2.全局变量容易被系统回收或者更改,使用全局变量前建议判空;
- 3.第三方接口的调用,对返回值进行判空。
- 4.请注意线程安全
- 空指针最为常见,也最容易规避,使用的时候一定要进行null check,采取不信任原则:
1.7 android.view.WindowManager$BadTokenException异常,Toast报错Unable to add window
- A.详细崩溃日志信息
- 报错日志,是不是有点眼熟呀?更多可以看我的开源项目:https://github.com/yangchong211
android.view.WindowManager$BadTokenException
Unable to add window -- token android.os.BinderProxy@7f652b2 is not valid; is your activity running?
- B.查看崩溃类信息
- 查询报错日志是从哪里来的

- C.项目中异常分析
- D.引发崩溃日志的流程分析
- 这个异常发生在Toast显示的时候,原因是因为token失效。通常情况下,一般是不会出现这种异常。但是由于在某些情况下, Android进程某个UI线程的某个消息阻塞。导致 TN 的 show 方法 post 出来 0 (显示) 消息位于该消息之后,迟迟没有执行。这时候,NotificationManager 的超时检测结束,删除了 WMS 服务中的 token 记录。删除 token 发生在 Android 进程 show 方法之前。这就导致了上面的异常。
- 测试代码。模拟一下异常的发生场景,其实很容易,只需要这样做就可以出现上面这个问题
Toast.makeText(this,"潇湘剑雨-yc",Toast.LENGTH_SHORT).show();
try {
Thread.sleep(20000);
} catch (InterruptedException e) {
e.printStackTrace();
}
- F.解决办法
- 目前见过好几种,思考一下那种比较好……
- 第一种,既然是报is your activity running,那可以不可以在吐司之前先判断一下activity是否running呢?
- 第二种,抛出异常增加try-catch,代码如下所示,最后仍然无法解决问题
- 按照源码分析,异常是发生在下一个UI线程消息中,因此在上一个ui线程消息中加入try-catch是没有意义的。而且用到吐司地方这么多,这样做也不方便啦!
- 第三种,那就是自定义类似吐司Toast的view控件。个人建议除非要求非常高,不然不要这样做。毕竟发生这种异常还是比较少见的
- G.哪些情况会发生该问题?
- UI 线程执行了一条非常耗时的操作,比如加载图片等等,就类似上面用 sleep 模拟情况
- 进程退后台或者息屏了,系统为了减少电量或者某种原因,分配给进程的cpu时间减少,导致进程内的指令并不能被及时执行,这样一样会导致进程看起来”卡顿”的现象
- 当TN抛出消息的时候,前面有大量的 UI 线程消息等待执行,而每个 UI 线程消息虽然并不卡顿,但是总和如果超过了 NotificationManager 的超时时间,还是会出现问题
1.8 java.lang.ClassCastException类转化异常
- A.详细崩溃日志信息
android.widget.FrameLayout cannot be cast to android.widget.RelativeLayout
com.paidian.hwmc.goods.activity.GoodsDetailsActivity.initView(GoodsDetailsActivity.java:712)
- B.查看崩溃类信息
- 抛出以指示代码试图将对象强制转换为它不是实例的子类。
public class ClassCastException extends RuntimeException {
private static final long serialVersionUID = -9223365651070458532L; public ClassCastException() {
super();
} public ClassCastException(String s) {
super(s);
}
}
- C.项目中异常分析
- 该异常表示类型转换异常,通常是因为一个类对象转换为其他不兼容类对象抛出的异常,检查你要转换的类对象类型。
- D.引发崩溃日志的流程分析
- F.解决办法
- 一般在强制类型转换时出现,例如如果A向B转换,而A不是B的父类时,将产生java.lang.ClassCastException异常。一般建议做这时要使用instanceof做一下类型判断,再做转换。
- 该案例中,需要把FrameLayout更改成RelativeLayout就可以呢
1.9 Toast运行在子线程问题,handler问题
- A.详细崩溃日志信息
- 先来看看问题代码,会出现什么问题呢?
new Thread(new Runnable() {
@Override
public void run() {
ToastUtils.showRoundRectToast("潇湘剑雨-杨充");
}
}).start();
- 报错日志如下所示:

- 然后找找报错日志从哪里来的
- 子线程中吐司的正确做法,代码如下所示
new Thread(new Runnable() {
@Override
public void run() {
Looper.prepare();
ToastUtils.showRoundRectToast("潇湘剑雨-杨充");
Looper.loop();
}
}).start();
- 得出的结论
- Toast也可以在子线程执行,不过需要手动提供Looper环境的。
- Toast在调用show方法显示的时候,内部实现是通过Handler执行的,因此自然是不阻塞Binder线程,另外,如果addView的线程不是Loop线程,执行完就结束了,当然就没机会执行后续的请求,这个是由Hanlder的构造函数保证的。可以看看handler的构造函数,如果Looper==null就会报错,而Toast对象在实例化的时候,也会为自己实例化一个Hanlder,这就是为什么说“一定要在主线程”,其实准确的说应该是 “一定要在Looper非空的线程”。
- Handler的构造函数如下所示:


关于其他内容介绍
01.关于博客汇总链接
02.关于我的博客
- 我的个人站点:www.yczbj.org,www.ycbjie.cn
- github:https://github.com/yangchong211
- 知乎:https://www.zhihu.com/people/yang-chong-69-24/pins/posts
- 简书:http://www.jianshu.com/u/b7b2c6ed9284
- csdn:http://my.csdn.net/m0_37700275
- 喜马拉雅听书:http://www.ximalaya.com/zhubo/71989305/
- 开源中国:https://my.oschina.net/zbj1618/blog
- 泡在网上的日子:http://www.jcodecraeer.com/member/content_list.php?channelid=1
- 邮箱:yangchong211@163.com
- 阿里云博客:https://yq.aliyun.com/users/article?spm=5176.100- 239.headeruserinfo.3.dT4bcV
- segmentfault头条:https://segmentfault.com/u/xiangjianyu/articles
崩溃bug日志总结1的更多相关文章
- C++后台服务崩溃堆栈日志
C++后台服务崩溃堆栈日志 C/C++后台服务运行过程中总会出现一些不容易重现的崩溃故障,由于重现频率低,同时运行在服务器上,导致无法调试,此外服务直接崩溃,常规日志无法截获到有用信息,这时如果能够保 ...
- android 程序崩溃crash日志的捕捉
android 程序崩溃crash日志的捕捉 之前在项目开发过程中,一直会遇到程序崩溃了,但是测试組的哥哥们又没及时的导出日志.... 后来在诳群的时候听别人说起,腾讯有那么一个叫bugly的东西 将 ...
- 谦先生的bug日志之hive启动权限问题
上海尚学堂谦先生的bug日志之hive启动权限问题 这几天开始做新老集群的迁移,今天开始对hive的所有数据进行迁移,主要是表的元信息和表数据.表的元信息我们存在mysql中,跟hive的服务器并不在 ...
- UNITY崩溃的日志
有关UNITY的日志,有两个路径. 1,一般日志路径:C:/Users/xxxx/ AppData/Local/Unity/Editor,此文件夹下有三个文件 ,如下图:Editor.log, Edi ...
- Python 中 对logging 模块进行封装,记录bug日志、日志等级
是程序产生的日志 程序员自定义设置的 收集器和渠道级别那个高就以那个级别输出 日志和报告的作用: 报告的重点在于执行结果(执行成功失败,多少用例覆盖),返回结果 日志的重点在执行过程当中,异常点,哪里 ...
- 漫谈:从APP崩溃率标准,到Monkey介绍拓展Maxim,及Jenkins自动化配置,持续集成获取崩溃monkey日志
漫谈:从APP崩溃率标准,到Monkey介绍拓展Maxim,及Jenkins自动化配置,持续集成获取崩溃日志 1.APP崩溃率标准 开发或测试app的同学,对于app崩溃肯定非常熟悉,频繁的线上崩溃属 ...
- 番外特别篇之 为什么我不建议你直接使用UIImage传值?--从一个诡异的相册九图连读崩溃bug谈起
关于"番外特别篇" 所谓"番外特别篇",就是系列文章更新期间内,随机插入的一篇文章.目前我正在更新的系列文章是 实现iOS图片等资源文件的热更新化.但是,这两天 ...
- 内存转储文件调试系统崩溃bug
百度百科:内存转储文件 内存转储是用于系统崩溃时,将内存中的数据转储保存在转储文件中,供给有关人员进行排错分析用途.而它所保存生成的文件就叫做内存转储文件. 内存转储文件也被称作虚拟内存,它是用硬盘里 ...
- bug日志-天坑,Spring Security的登陆报错:An internal error occurred while trying to authenticate the user.
在学习Spring Security的时候,我的编辑器给我报错:An internal error occurred while trying to authenticate the user. 明明 ...
- 新版本读取老版本文件崩溃BUG
读取文件匹配代码 BOOL CWBPage::LoadFromFile(CFile *pFile, LONGLONG& lOff, ULONGLONG lFileLength) { if (p ...
随机推荐
- 《ASP.NET Core 与 RESTful API 开发实战》-- (第9章)-- 读书笔记(上)
第 9 章 测试和文档 9.1 测试 测试是软件生命周期中的一个非常重要的阶段,对于保证软件的可靠性具有极其重要的意义 常见的测试方法有很多,根据不同的维度,可以把测试方法分为不同的类别 从观察结构的 ...
- Pandas—read_csv()/read_table()文本文件的读取
对于CSV及txt后缀的文本文件,分别使用pandas模块中的read_csv函数和read_table函数 文件类型 函数名称 CSV read_csv() txt read_table() 1. ...
- Hadoop的stop-all无法关闭集群原因及解决方案
问题现象:在服务器上长时间运行hadoop之后,如果运行stop-all.sh,会发现: [root@node1 sbin]# stop-all.shThis script is Deprecated ...
- 开源.NetCore通用工具库Xmtool使用连载 - 随机值篇
[Github源码] <上一篇> 详细介绍了Xmtool工具库中的散列算法类库,今天我们继续为大家介绍其中的随机值类库. 基于系统提供的Random获取随机值方法已经足够简单和易用,本类库 ...
- NC18987 粉嘤花之恋
题目链接 题目 题目描述 qn是个特别可爱的小哥哥,qy是个特别好的小姐姐,他们两个是一对好朋友 [ cp (划掉~) 又是一年嘤花烂漫时,小qn于是就邀请了qy去嘤花盛开的地方去玩.当qy和qn来到 ...
- STC12硬件SPI驱动MAX7219点阵LED
max7219是一个用于驱动8位7段数字LED或者8x8点阵LED的驱动芯片, 以列扫描的方式, 用16个pin管理64个发光点, 显示8个数字时刷新率为500-1300Hz, 典型值为800Hz. ...
- CentOS在无网络环境下,用离线源yum安装软件
先说大致步骤: 1.前提假设:当前无网络的目标服务器是A,我们需要先准备一台服务器B: 2.在B上面用yum先把软件安装完成. 3.然后用createrepo将B中的包拷贝出来,并传到A上(用U盘或者 ...
- 石子合并(区间dp+记忆化搜索)
经典例题:石子合并 题目链接 N 堆石子排成一行,现要将石子有次序地合并成一堆,规定每次只能选相邻的2堆合并成新的一堆,并将新的一堆的石子数,记为该次合并的得分.计算合并最小得分. 方法一.区间dp ...
- C++ sentry 如何压缩日志文件
项目中在使用 sentry 上传事件的 attachment 函数过程中发现,附带的 log 文件是未压缩的,于是有了需求,即需要在 sentry 内部将未压缩的文件流压缩后再上传给服务器 这个需求看 ...
- 关于谷歌浏览器出现“错误代码:net::ERR_UNSAFE_PORT”的解决办法
搭建项目时需要自己配置端口信息,但是有人搭建之后会出现如下情况 但是换用edge等浏览器没有问题,这是因为chorme浏览器有自己的默认非安全端口, 若访问这些端口就会出现这个错误,并且所有采用cho ...