当前位置:   article > 正文

Android 的闪退,崩溃等分析思路

androidruntime: shutting down vm

阅读本文预计需要8分钟

时常有同学来问我这个错误怎么解决,那个错误怎么解决,所以才写这篇文章来阐述一下Android的一些错误日志如何去分析,有经验的工程师其实都知道,错误大同小异,根据步骤来解决即可,不过时下不比以前,现在的错误五花大门倒也是真的,有Android本身的错误,Gradle的编译错误,ANR的错误,以及一些so底层的错误,我们一个个来吧。

 

第一步:找到错误,这个相信不用去讲了,要是你连错误都找不到,我...我 .....

       640?wx_fmt=png      

 

好吧,给你一个参照物

 

       640?wx_fmt=png      

 这是最普通的Exception了,这个错误是在Android Studio的底部有一个logcat菜单中查找,我们再来看下另外的错误吧,比如Gradle编译的错误,其实Gradle编译的错误很多,这里列举一个:

       640?wx_fmt=png  

 

Gradle编译的错误在Android Studio的底部有一个build菜单中查找,分为两类,左边是错误发生的位置,此类错误还比较好,会告诉你发生的错误位置,有些错误就不会告诉你了,右边是具体的错误问题解释。

 

接下来还有ANR的错误,ANR的错误辨识度很高,因为屏幕上会弹出 应用已停止运行 的提示框。

 

好了,接下来我们就开始一个个教大家如何分析吧,我们主要分为Android运行时的错误,以及Gradle编译的错误,还有ANR的解决,至于so库的问题就不讲解了,开始吧。

 

       640?wx_fmt=png      

一.AndroidRuntime

我们还是拿刚才的这个错误来对比:

        640?wx_fmt=png       

这张错误的截图其实只是一部分,一看蓝色部分就知道他指向的是我们MainActivity的19行,那么如果不知道如何定位的同学如何去定位呢?那就要通过我们的AndroidRuntime了,实际上他的自身含义就是Android运行时发生的错误,我们来看下完整截图:

       640?wx_fmt=png      

 当错误发生的时候,首先AndroidRuntime会打印一个Shutting down VM,说明应用已经挂掉了,然后会打印--------- beginning of crash来开始搜集我们的crash,再接着AndroidRuntime就会开始打印他认为的错误原因,最后在 Caused by 中就是具体的问题了,如果他能追踪到行数,就会为你标记为蓝色可执行文本,而我们看到这个错误就是我们日常所见的一个很普通的错误:NullPointerException 空指针异常,那么我们定位到了这个异常的类型,就好办了,先来认识下一些常见的异常吧:

        640?wx_fmt=png       

 这张图中我们看到我列举了三个,当然,异常肯定有很多我就以这三个为例,给大家抛砖引玉。

1.NullPointerException

首先我们回到上面的错误,他既然是一个空指针异常,那么肯定是有一个对象为空的,我们来看下他对应的MainActivity第19行具体的代码:

       640?wx_fmt=png       

这里是一个控件设置点击事件,那么既然我们怀疑有对象为空,那么我们来看这一行实际上就一个mBtn是一个引用对象,而OnclickListener是当场New出来的,那么mBtn我们来看,我们怀疑他是空对象,那么就得回忆下,如何初始化一个控件对象了,在Android中我们初始化一个控件对象是通过findViewById来实现的,到这你就会发现,自己没有findViewById来初始化,导致了空指针,例子很简单,一看就明白,但是要理解解题的思路。

       640?wx_fmt=png      

 

2.ActivityNotFoundException

那么我们继续来看下其他错误吧,比如ClassNotFoundException,顾名思义,找不到类报的异常,我们先来看下他的Log:

       640?wx_fmt=png

 

这个错误是否符合我们之前分析的几个要素呢?实际上大部分都是有的,你可以看到Shutting down VM的打印,也可以看到 FATAL EXCEPTION ,他的错误是ActivityNotFoundException,也就是找不到Activity的异常,和我们所说的ClassNotFoundException不一样,但是列表差不多,我们以此来分析问题,第一眼看过去,我们看到他提示了这么一段话:

 

have you declared this activity in your 

AndroidManifest.xml?

//您是否在AndroidManifest.xml中声明了此活动?

 

带着这个问题我们来到了他所指向的MainActivity第24行看到这样一段代码:

       640?wx_fmt=png       

这段代码中指向的是一个startActivity,也就是我们想跳转到HelloActivity中,但是失败了,提示我们是否在清单文件中注册?这就很好理解了,我们的Activity需要在清单文件中注册才能跳转,而现在报了这个异常,说明我们没有注册,去注册下就好了。

 

       640?wx_fmt=png      

接下来再看我们最后一个数组越界的异常吧。

3.ArrayIndexOutOfBoundsException

先来看下数组越界的异常打印的Log是什么:

       

640?wx_fmt=png

 

这段错误,我们可以这样去分析,首先找到我们的几个关键点:

 

1.错误的解释:

java.lang.IndexOutOfBoundsException: Index: 8, Size: 5

2.错误的异常:IndexOutOfBoundsException

3.错误的定位:onCreate(MainActivity.java:38)

 

有了这三点就再简单不过了,我们可以确定是一个数组越界的异常,而给到我们的解释是:Index: 8, Size: 5 ,这要如何解释?下标:8  数量:5 ,这就需要结合实际的代码来看了,我们定位到的行数是MainActivity的38行,来看下:

       640?wx_fmt=png

 

这段代码中我们声明了一个list并且使用for循环遍历了5遍填充数据,然后打印他的第8个值,其中出现的数值就是5和8,这也验证了我们刚才的错误提示:Index: 8, Size: 5

 

也就是说,你的size只有5,但是你获取的index下标确是8,我肯定是没有的,就提示了这个异常了

       640?wx_fmt=png      

 

所以你会发现其实这些错误,大部分出现的问题都是能顺藤摸瓜的,只要抓到问题,分析问题基本都有思路,不过AndroidRuntime的错误毕竟很多人都会解决,那么我们来看下,编译的时候的问题吧。

二.Gradle 编译问题

Gradle编译的问题很多,有一小部分还是很让人头疼的,我们一步步来,先解决Gradle版本的问题、

1.Gradle版本

你是否碰到过项目突然无法编译,出现一些奇奇怪怪的错误,或者说你去Github上Clone了一个项目打算导入Android Studio却死活无法运行,这些大部分都是Gradle版本的问题,如果你无法在线下载Gradle的话就需要本地离线去下载了。

 

这里你可以先打开Android Studio

File > Settings > Appearance & Behavior > System Settings > HTTP Proxy

再配置这个地址与端口:

127.0.0.1 1080

 

看看有没有效果,如果无效的话就自己手动下载吧。

 

先打开地址:

http://services.gradle.org/distributions/

 

选择你要下载的版本下载好之后,打开:

C:\Users\Administrator\.gradle\wrapper\dists\gradle-5.4.1-all\3221gyojl5jsh0helicew7rwx

 

dists目录下面是你具体的版本号,我的是5.4.1-all

 

然后把你下载的zip放入这个目录解压出来,重启AS即可。

2.Jar冲突

Jar冲突可以这样理解:

       640?wx_fmt=png      

这张图中,如果一个APP引用了两个开源框架,A 和 B,然后他们内部又同时依赖了OkHttp,而且还有一种可能就是他们引用的OkHttp版本都不同,这就出现了Jar的冲突了,那么如何解决呢?

 

使用exclude标签来解决这个问题:

       640?wx_fmt=png      

 假设冲突的是zxing,那么通过exclude去除zxing,这样就可以解决了,如果你告诉我你不知道哪两个框架冲突了,这里可以告诉你一些办法:

 

1.gradlew -q app:dependencies  会列出所有的依赖关系

2.定位到冲突的类,双击Shift去查找

 

我一般是第二种,比如我知道OkHttp冲突了(可以从Gradle的Log中看到),然后去查到了

        640?wx_fmt=png       

 还有很多的错误,还是需要自己去挖掘和分析的,我们接着来看ANR吧。

 

       640?wx_fmt=png      

三.ANR

应用无法响应,可以是死循环,线程休眠,也可能是某个机制超时,比如触摸超时,服务,广播,内容提供者等超时,他们都会弹出一个提示框

 

       640?wx_fmt=png      

 

我们可以在logcat中看到这样的信息:

       640?wx_fmt=png      

 

可以看到他与我们的AndroidRuntime很不一样,不过可以从中得到一段很关键的话:

 

 Reason: Input dispatching timed out (Waiting to send non-key event because the touched window has not finished processing certain input events that were delivered to it over 500.0ms ago.  Wait queue length: 6.  Wait queue head age: 6315.7ms.)

 

//输入超时

 

如果你有经验的话,你就能猜到是卡UI线程了,等待一定时间超时引起的,那么我们如何追踪呢?可以分析traces文件

1.traces.txt

traces文件就是保存ANR信息的log,位于 data/anr 目录下,记录着堆栈的信息,可以通过如下命令获取

 

adb root

adeb remount

adb pull /data/anr/traces.txt c:\

 

这样就拉取到C盘根目录了,不过部分手机是没有权限的,所以我们也可以借助一些Carsh的SDK来帮助我们获取问题,比如Bugly

 

       640?wx_fmt=png      

四.Bugly

官网:https://bugly.qq.com/v2/

 

集成起来还是很方便的,添加源:

 

implementation 'com.tencent.bugly:crashreport:2.2.0'

implementation 'com.tencent.bugly:nativecrashreport:3.0'

 

别忘了设置支持的架构:

       640?wx_fmt=png      

 

再添加一些权限:

 

<uses-permission android:name="android.permission.READ_PHONE_STATE" />

<uses-permission android:name="android.permission.INTERNET" />

<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />

<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />

<uses-permission android:name="android.permission.READ_LOGS" />

 

最后在Application中初始化一下

 

CrashReport.initCrashReport(getApplicationContext(), "注册时申请的APPID", true);

 

initCrashReport方法中最后一个参数是一个debug开关,声明是否需要打印bugly的日志,建议debug的时候打开,release的时候关闭

 

然后就可以在应用后台中看到相关数据和Log了,不管是线上线下,都能提前清楚问题,尽快修复。

 

       640?wx_fmt=png      

 

这就是本文的全部内容了

 

       640?wx_fmt=jpeg      

写这篇文章呢,其实没多少技术在其中,更多的是一种科普,让同学们对解决问题的思路有一个了解,也好提高自己的开发效率

 

有兴趣的可以加入我的知识星球哦,只要点击阅读原文即可哦~

关于知识星球的介绍可以在公众号点击右下角的【和我学习】或者公众号发送【Hi Android】【知识星球】都可以

640?wx_fmt=jpeg

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/Monodyee/article/detail/292471
推荐阅读
相关标签
  

闽ICP备14008679号