崩溃优化小结

Java层崩溃

崩溃产生的原因

  • 当有异常没有在代码中捕获到时,JVM会帮我们调用Thread.dispatchUncaughtException方法

  • 在这个方法中会判断有没有设置UncaughtExceptionHandler;如果有则让它调用uncaughtException方法处理异常;如果没有则使用默认的异常处理器进行处理

  • 在app进程刚创建的时候,(RuntimeInit.java)会给线程设置一个默认的异常处理器KillApplicationhandler,这个默认异常处理器会将异常信息上报AMS,然后杀死app进程

解决办法

  • 给Thread设置一个全局的异常处理器,在里面收集崩溃信息并上报服务器

  • 正常崩溃会杀死整个app进程,捕获异常后可以仅关闭当前显示的Activity,提升用户体验

  • 一般崩溃都是发生在主线程Looper处理消息过程中,我们可以在Looper循环处理消息外面一层加上try/catch,从而避免应用被杀死;

    • 具体做法是通过Handler在主线程Looper发送一个消息,在这个消息中开启一个无限循环,循环里调用Looper.loop()并用try/catch包裹起来,当异常发生时会被捕获,从而又重新开启一个循环去遍历消息,达到不崩溃目的

    • Handler(Looper.getMainLooper()).post {
              
              
          while (true) {
              
              
              try {
              
              
                  Looper.loop()//开启新的循环
              } catch (e: Throwable) {
              
              
                  e.printStackTrace()
              }
          }
      }
      

Native层崩溃

系统native崩溃监测

  • 在SystemServer启动系统服务时,会通过AMS创建一个NativeCrash监听,通过监听native层crash信号量,判断是崩溃后会将崩溃信息通过DropBoxManager保存到/data/system/dropbox目录下

应用内native层崩溃监测

  • 通过JNI在native层监听crash有关的信号量,然后回调java层方法记录并保存起来

  • ndk提供addr2line工具可以根据内存地址定位代码行数

  • 第三方框架:breakpad、腾讯Bugly

ANR

ANR的种类

Input事件和Service\广播、ContentProvider没有在规定时间内处理完事件

  • “Input event dispatching timed out” =》5秒内没有响应触摸事件

  • “Time out executing service” =》Serveice未在规定时间内启动完成,前台服务20秒,后台200秒

  • “Time out of broadcast BroadcastRecord” => 未在规定时间内处理完广播,前台广播10秒,后台广播60秒

  • “time out publish content provider” => ContentProvider没有在10秒内publish完

ANR产生的原因

  • 系统在检测ANR时主要在处理事件之前通过Handler发送一个延迟消息,如果在规定时间内处理完则移除消息,否则执行ANR操作,将ANR信息保存起来并弹出ANR窗口提示;ANR信息被保存在在/data/anr/traces.txt文件中;

  • 在应用层主要是主线程做了耗时操作、或者频繁触发GC、死锁等问题造成的

ANR问题分析

  • 通过系统log查看anr发生的时间、进程id、包名、ANR类型等信息

  • 分析ANR发生时CPU占用情况,如果app占用率比较高,则认为是app的问题,如果是系统cpu占用率比较高,则可能是系统原因导致的

  • 接着分析ANR的trace文件,主要看main主线程的状态,以及打印的堆栈信息定位发生ANR位置;比如当时主线程是不是在等待其他锁的释放,或者处理sleep、wait等状态等等

ANR监测

  • 通过FileObserver监测data/anr/目录下的文件变化,当ANR发生时会在该目录下生成trace文件;腾讯Bugly就是这种实现方式

  • 开启一个单独的线程,通过Handler往主线程上修改一个变量,如果在设定的时间内没有修改成功,则认为发生了ANR,然后获取主线程调用栈信息;ANR-WatchDog的实现方式

  • 在native层监听ANR发生时的信号量实现;微信实现方式

其他崩溃

  • wtf(What a Terrible Failure):一般是值没有安装Android官方要求编码抛出的异常,比如发送了未受保护的广播,在后台服务启动Activity时没有添加Intent.FLAG_ACTIVITY_NEW_TASK标签等等

猜你喜欢

转载自blog.csdn.net/guangdeshishe/article/details/129903028