笔记:Android常规Crash方案

引言:Crash崩溃在Android程序开发中总是会遇见的,在本地调试的还好我没通常可以通过logcat日志打印来分析输出的日志 定位到问题。但是上了线各种复杂的环境就没那么好处理。这时候通常我会集成像Bugly这种sdk来分析问题。但是Bugly又是怎么做到crash的采集呢?

Crash分类:

  • Java层崩溃Crash:

Java层的崩溃一般比较好捕捉 java中的Thread提供了异常处理接口 Thread.UncaughtExceptionHandler

public class CrashHanler  implements  Thread.UncaughtExceptionHandler{
    private static Thread.UncaughtExceptionHandler mDefaultExceptionHandler;
    private static Context mContext;

    public static void init(Context context){
        mContext = context;
        //获取默认ExceptionHandler
        mDefaultExceptionHandler = Thread.getDefaultUncaughtExceptionHandler();
        //设置程序开发者的自行异常处理器 发生异常会回调到 uncaughtException
        Thread.setDefaultUncaughtExceptionHandler(new CrashHanler());
    }

    @Override
    public void uncaughtException(@NonNull Thread thread, @NonNull Throwable throwable) {
        //异常回调处理方法
        File crashFileDir = new File(mContext.getExternalFilesDir("crashReport"),"crash_info");
        if(!crashFileDir.exists())
            crashFileDir.mkdirs();
        long time = System.currentTimeMillis();
        String dateTimeStr = DateFormat.format("yyyy年MM月dd日 HH时mm分ss秒",time).toString();
        String dateTimeFileStr = DateFormat.format("yyyyMMssHHmmss",time).toString();
        File crashFile = new File(crashFileDir,dateTimeFileStr+".log");
        //使用打印流打印到文件分
        try {
            PrintWriter pw = new PrintWriter(crashFile);
            pw.println("crash发生线程:"+ thread.getName());
            pw.println("时间:"+dateTimeStr);
            pw.println("设备与APP版本信息:"+getDevicePhoneInfo());
            pw.println("错误堆栈:");
            throwable.printStackTrace(pw);
            pw.close();
        } catch (FileNotFoundException e) {

            e.printStackTrace();
        } catch (PackageManager.NameNotFoundException e) {
            e.printStackTrace();
        }finally {
            if(mDefaultExceptionHandler!=null)
                mDefaultExceptionHandler.uncaughtException(thread,throwable);
        }
    }

    private static String getDevicePhoneInfo() throws PackageManager.NameNotFoundException {...}
}

捕获记录文件.png
  • Native层崩溃Crash:

集成 google 的 breakpad 框架

ndk部分.png

JNI部分,先写native方法

public static native void initNativeCrash(String path);

native实现

#include <jni.h>
#include <android/log.h>
#include "breakpad/src/client/linux/handler/exception_handler.h"
#include "breakpad/src/client/linux/handler/minidump_descriptor.h"
extern "C"
JNIEXPORT void JNICALL
Java_com_chenx_crashreportproject_CrashReportManager_testNativeCrash(JNIEnv *env, jclass clazz) {
    __android_log_print(ANDROID_LOG_INFO,"testNative","xxxxxxx test NDK Native crash. xxxxxxxx");
    int *p = NULL;
    *p = 10;
 }
 bool DumpCallback(const google_breakpad::MinidumpDescriptor &descriptor,
         void* context,
                   bool succeeded){
    __android_log_print(ANDROID_LOG_ERROR,"native","native crash:%s",descriptor.path());
     return false;
}

 extern "C"
 JNIEXPORT void JNICALL
 Java_com_chenx_crashreportproject_CrashReportManager_initNativeCrash(JNIEnv *env,jclass clazz,jstring filepath){
     const char* path = env->GetStringUTFChars(filepath,0);
     __android_log_print(ANDROID_LOG_INFO, "native", "===> %s", path);
     google_breakpad::MinidumpDescriptor descriptor(path);
     static google_breakpad::ExceptionHandler eh(descriptor, NULL, DumpCallback,
                                                 NULL, true, -1);
     env->ReleaseStringUTFChars(filepath,path);
}
1.通过linux的信号分发机制我们设置我们自己异常处理器就可以捕抓到native层的错误 但是文件我们是打不开的。这个时候如果是window系统 我们可以用minidump工具来转文件 minidump位于:AndroidStudio 安装目录下的\bin\lldb\bin
minidump目录.png
2.然后通过cmd运行命令

minidump_stackwalk C:\Users\86136\Desktop\b47fc729-680c-4a62-7fd8b3ad-9ad095d9.dmp >myCrash.txt
这样就可以得到我们可读的crash文件

myCrash文件的一部分.jpg

3.再通过ndk目录下的aar64-linux-android-addr2line 工具来确定定位错误位置
native crash定位

项目源码:https://gitee.com/DaiMaZhiJia/CrashReportProject

©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

  • 最近应项目需求,准备做崩溃日志收集框架,前期简单调研一番。 一、日志收集方案 类型名称描述说明java crash...
    Stan_Z阅读 10,231评论 1 8
  • Crash(应用崩溃)是由于代码异常而导致 App 非正常退出,导致应用程序无法继续使用,所有工作都停止的现象。发...
    wuchao226阅读 5,011评论 0 0
  • 一.概述   本文主要介绍Android平台下bug类型和产生原因、崩溃捕获和收集解决方案、以及bugly的使用方...
    Haraway阅读 13,200评论 3 14
  • 个人博客http://www.milovetingting.cn[http://www.milovetingtin...
    milovetingting阅读 4,003评论 0 3
  • 一般应用在运行时,不可避免的会发生crash。一般应用crash分为三种:未捕获的异常、ANR(Applicati...
    潇潇凤儿阅读 26,108评论 1 25

友情链接更多精彩内容