- 
 ● 本文通过学习别人写demo,学习一些课件,参考一些博客,’学习相关知识,如果涉及侵权请告知
 ● 本文只简单罗列相关的代码实现过程
 ● 涉及到的逻辑以及说明也只是简单介绍,主要当做笔记,了解过程而已

█ 我的问题:

- 
 ● app在手机上面安装测试时,总是会遇到奔溃问题,而不是在线调试,那么怎么查看奔溃的原因?
 
 ● 如果你app直接在Google Play上面上线,你会发现他会自动给收集奔溃报告,而且不需要你做任何的集成工作。
 
 ● 目前市场上也有很大异常上报的第三方库,让我们百度看看下吧。

█ 第三方库:

- 
 ● Bugly
  腾讯出品的SDK,大公司,文档很齐全,很规范,能搜集到JNI层的奔溃以及监控线上的ANR问题。
  不过在使用过程中,会发现有时候奔溃了,不上报,尤其是用久的App ID,基本上重新创建一个产品,替换成新的App ID就解决了。

为什么我完成了Bugly集成,在页面还是看不到日志?
请检查:
1)AppId是否设置正确(若设置错误,请更正后卸载App重试);
2)初始化SDK是否在Crash之前完成;
3)网络是否可用;
4)测试时如果之前有上报突然不上报了,可能是因为Bugly有流量保护,请卸载App后再试(它并不影响真实用户Crash准确度);
5)Bugly会在发生Crash时尝试尽量上报。如果失败,会在下次启动选择合适的时机上报;

● U-App(移动统计)-稳定性
  稳定性监测和分析模块是友盟+ U-App 产品为移动开发者提供的 App 崩溃、卡顿等异常信息收集和分析工具,帮助开发者监测 App 在移动设备上的异常状况,及时发现并解决错误,提升 App 的稳定性。
  2013年阿里巴巴收购的移动开发者服务平台友盟,因此也是属于大公司产品,文档也是一流的。

● ACRA
  ACRA是Google推出的开源Android应用Crash reports崩溃日志搜集器框架。在Android平台上处理未捕获异常,并在崩溃时收集各种设备及上下文信息,并生成崩溃报告,保存到本地文件,并使用合适的机制将所有的崩溃报告上报给服务器等一整套开源解决方案。可以轻松让你实现客户端的崩溃日志上传到后台,有一个不足之处,就是它搜集不到JNI层的奔溃。

ACRA的通知系统很干净。 如果发生崩溃,您的应用程序不会在现有系统的崩溃通知或报告功能上添加用户通知。 默认情况下,不再显示“强制关闭”对话框,启用它会将 allReportToAndroidFramework 设置为true。
(1)这里formKey可以不填,没有啥大的作用;
(2)这里采用的是退出时候,会弹出Toast,resToastText = R.string.crash_toast_text为显示的内容。 forceCloseDialogAfterToast = false表示不弹出对话框。
(3)这里使用的是post提交,ReportField.APP_VERSION_NAME为上传的字段,也就是url的参数。
(4)使用的时候,只需要在我们继承的Application的子类总加入ACRA.init(this); 就可以了。

● 还有其他的一些第三方库,如Crashlytics(国外的一个SDK)

● 自定义的Crash收集:

  1. 实现Thread.UncaughtExceptionHandler接口
    2.将当前类设为默认异常处理器 Thread.setDefaultUncaughtExceptionHandler(this);

█ 总结:

- 
 ● Bugly会出现漏上报,但是后台统计比较齐全,因此目前就将Bugly和ARCA两个相结合一起使用

1 在MyApplication中进行初始化,注意顺序
ACRA.init(this); // 调用init方法,对acra进行初始化
 CrashReport.initCrashReport(this, BUGLY_KEY, true);// true表示异常立刻上报,建议在测试阶段建议设置成true,发布时设置为false。2 重写异常时,发送邮件(在这边如果写Log.e会发现没有打印出来,不知道什么原因)
public class YourOwnSender implements ReportSender {
 @Override
 public void send(@NonNull Context context, @NonNull CrashReportData crashReportData) throws ReportSenderException {MyUtils.sendByMail(crashReportData.toString()); //发送邮件
}
 }

● ARCA上报日志的内容如下:

07-29 17:40:10.879 E/CrashReport( 3584): sys default last handle start!
07-29 17:40:10.883 E/ACRA    ( 3584): ACRA caught a RuntimeException for com.my.bx
07-29 17:40:10.883 E/ACRA    ( 3584): java.lang.RuntimeException: This Crash create for Test! You can go to Bugly see more detail!
07-29 17:40:10.883 E/ACRA    ( 3584): at com.tencent.bugly.crashreport.CrashReport.testJavaCrash(BUGLY:149)
07-29 17:40:10.883 E/ACRA    ( 3584): at com.my.bx.fragment.main.frontCash.FrontCashFragment.onViewClicked(FrontCashFragment.java:166)
07-29 17:40:10.883 E/ACRA    ( 3584): at com.my.bx.fragment.main.frontCash.FrontCashFragment_ViewBinding$2.doClick(FrontCashFragment_ViewBinding.java:60)
07-29 17:40:10.883 E/ACRA    ( 3584): at butterknife.internal.DebouncingOnClickListener.onClick(DebouncingOnClickListener.java:22)
07-29 17:40:10.883 E/ACRA    ( 3584): at android.view.View.performClick(View.java:5657)
07-29 17:40:10.883 E/ACRA    ( 3584): at android.view.View$PerformClick.run(View.java:22453)
07-29 17:40:10.883 E/ACRA    ( 3584): at android.os.Handler.handleCallback(Handler.java:751)
07-29 17:40:10.883 E/ACRA    ( 3584): at android.os.Handler.dispatchMessage(Handler.java:95)
07-29 17:40:10.883 E/ACRA    ( 3584): at android.os.Looper.loop(Looper.java:154)
07-29 17:40:10.883 E/ACRA    ( 3584): at android.app.ActivityThread.main(ActivityThread.java:6119)
07-29 17:40:10.883 E/ACRA    ( 3584): at java.lang.reflect.Method.invoke(Native Method)
07-29 17:40:10.883 E/ACRA    ( 3584): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:886)
07-29 17:40:10.883 E/ACRA    ( 3584): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:776), IS_SILENT=false, USER_EMAIL=}

● 虽然ARCA可以弥补Bugly漏上报问题,但是却在应用奔溃会,不会有任何提示框提示,而是直接退出应用,如果想要对话框提示,则需要在注解中添加相应的设置:

mode = ReportingInteractionMode.DIALOG,
        resDialogText = R.string.crash_dialog_text,
        resDialogTitle = R.string.crash_dialog_title

不过对话框也太丑了,另外对话框还是固定存在取消按钮,目前使用的版本是’ch.acra:acra:4.11.1’:

android 系统级crash如何解决 安卓 crash_java


可以查看org.acra.dialog.CrashReportDialog源码:setNegativeButton(表示设置弹框后的取消按钮)

/**
     * Build the dialog from the values in config
     *
     * @param savedInstanceState old state to restore
     */
    protected void buildAndShowDialog(@Nullable Bundle savedInstanceState) {
        final AlertDialog.Builder dialogBuilder = new AlertDialog.Builder(this);
        final int titleResourceId = getConfig().resDialogTitle();
        if (titleResourceId != ACRAConstants.DEFAULT_RES_VALUE) {
            dialogBuilder.setTitle(titleResourceId);
        }
        final int iconResourceId = getConfig().resDialogIcon();
        if (iconResourceId != ACRAConstants.DEFAULT_RES_VALUE) {
            dialogBuilder.setIcon(iconResourceId);
        }
        dialogBuilder.setView(buildCustomView(savedInstanceState))
                .setPositiveButton(getText(getConfig().resDialogPositiveButtonText()), this)
                .setNegativeButton(getText(getConfig().resDialogNegativeButtonText()), this);

        mDialog = dialogBuilder.create();
        mDialog.setCanceledOnTouchOutside(false);
        mDialog.show();
    }