Crashlytics Android SDK - 自定义 UncaughtExceptionHandler

Posted

技术标签:

【中文标题】Crashlytics Android SDK - 自定义 UncaughtExceptionHandler【英文标题】:Crashlytics Android SDK - custom UncaughtExceptionHandler 【发布时间】:2014-10-01 22:34:09 【问题描述】:

是否可以在一个应用程序中结合自定义 UncaughtExceptionHandler 和 crashlytics?如果是 - 如何?

【问题讨论】:

这个好运吗?我也遇到了新的遗物同样的问题。发现代码无法进一步链接未捕获的异常。 @SephRemotigue 试试这个解决方案***.com/a/56990688/6445611 【参考方案1】:

更新

请参阅@kmityak answer,因为 Crashlytics/Fabric 初始化现在是异步的,我下面的解决方案不再有效。

原始答案

您可以设置您的自定义 UncaughtExceptionHandler,前提是它将异常传递给默认 UncaughtExceptionHandler,以便稍后通过 Crashlytics 处理。

以下代码在 Application 子类中实现:

private static Thread.UncaughtExceptionHandler mDefaultUEH;
private static Thread.UncaughtExceptionHandler mCaughtExceptionHandler = new Thread.UncaughtExceptionHandler() 
    @Override 
    public void uncaughtException(Thread thread, Throwable ex) 
        // Custom logic goes here

        // This will make Crashlytics do its job
        mDefaultUEH.uncaughtException(thread, ex);
    
;

@Override
public void onCreate() 
    super.onCreate();

    // Order is important!
    // First, start Crashlytics
    Crashlytics.start(this);

    // Second, set custom UncaughtExceptionHandler
    mDefaultUEH = Thread.getDefaultUncaughtExceptionHandler();
    Thread.setDefaultUncaughtExceptionHandler(mCaughtExceptionHandler);

第二个选项是设置您的自定义 UncaughtExceptionHandler 之后注册 Crashlytics - 然后 Crashlytics 将所有未捕获的异常报告为致命异常,然后传递给您的自定义处理程序。

【讨论】:

我没有得到方法Crashlytics.start(this)。我正在使用crashlytics:2.5.1。我只想退出我的应用程序并向 Fabric 发送报告。我该怎么做? 使用Fabric.with(this, Crashlytics()) 而不是Crashlytics.start(this) 你能告诉我,代码到底属于哪里吗?我不明白... inside Application subclass 是什么意思。谢谢! 您需要创建一个自定义的 Applicaiton 类。您可以通过创建 android.app.Application 的子类并将其注册到 AndroidManifest.xml 中来实现。更多信息在这里:developer.android.com/reference/android/app/Application.html【参考方案2】:

由于最近版本的 Crashlytics 异步执行初始化,最好使用 Fabric 的初始化回调:

private static Thread.UncaughtExceptionHandler mDefaultUEH;
private static Thread.UncaughtExceptionHandler mCaughtExceptionHandler = 
   new Thread.UncaughtExceptionHandler() 
     @Override 
public void uncaughtException(Thread thread, Throwable ex) 
        // Custom logic goes here

        // This will make Crashlytics do its job
        mDefaultUEH.uncaughtException(thread, ex);
    
;

CrashlyticsCore core = new CrashlyticsCore.Builder()
            .disabled(BuildConfig.DEBUG)
            .build();
Fabric.with(new Fabric.Builder(this).kits(new Crashlytics.Builder()
            .core(core)
            .build())
            .initializationCallback(new InitializationCallback<Fabric>() 
                @Override
                public void success(Fabric fabric) 
                    mDefaultUEH = Thread.getDefaultUncaughtExceptionHandler();
                    Thread.setDefaultUncaughtExceptionHandler(mCaughtExceptionHandler);
                

                @Override
                public void failure(Exception e) 

                
            )
            .build());

【讨论】:

从我在 CrashlyticsCore (v2.9.4) 中看到的,CrashlyticsController.enableExceptionHandling() 在 onPreExecute() 内部被调用。所以这仍然在同一个线程中完成。 CrashlyticsUncaughtExceptionHandler(控制器使用)也确保它将异常传递给任何存在的默认处理程序。因此,初始化 Fabric 的顺序和您自己的异常处理程序无关紧要,只要您执行相同操作即可。 我在我的应用程序类中尝试了这个,在我的情况下失败(异常 e)收到一个异常的回调:“com.crashlytics.sdk.android.crashlytics-core 初始化被取消”。任何想法,为什么会发生这种情况? 我正在尝试这个,但 InitializationCallback 没有被调用。有什么想法吗?【参考方案3】:

如果这些解决方案对我有用,则无。我是这样做的:

// Setup handler for uncaught exceptions.
Thread.setDefaultUncaughtExceptionHandler (new Thread.UncaughtExceptionHandler()

    @Override
    public void uncaughtException (Thread thread, Throwable e)
    
        //Send Report to Crashlytics. Crashlytics will send it as soon as it starts to work
        Crashlytics.logException(e);

        //Your custom codes to Restart the app or handle this crash
        HandleCrashes(thread, e);
    
);

这是我重启APP的自定义方法:

private void HandleCrashes(Thread t, Throwable e) 

    Intent i = new Intent(mContext, frmLogin.class);
    i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK);
    i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
    i.putExtra("JustLogin", true);
    startActivity(i);

    System.exit(1);

【讨论】:

这个解决方案的问题是,Crashlytics 会将这个崩溃报告为非致命的,而不是一般的崩溃。 @VitoValov 有什么办法解决这个问题吗?仍然作为致命崩溃发送并重新启动应用程序?【参考方案4】:

    关闭自动收集

    将此添加到您的AndroidManifest.xml

<meta-data
     android:name="firebase_crashlytics_collection_enabled"
     android:value="false" />
    注册您的客户UncaughtExceptionHandler
Thread.setDefaultUncaughtExceptionHandler(customerUncaughtExceptionHandler)
    注册 UncaughtExceptionHandler 后手动启动 Crashlytics
Fabric.with(this, new Crashlytics());
    重建并重新安装您的应用程序

【讨论】:

【参考方案5】:

是的,有可能。

在您的应用程序类中:

@Override
public void onCreate() 
    super.onCreate();
    Crashlytics.start(this);
    initUncaughtExceptionHandler();


private void initUncaughtExceptionHandler() 
    final ScheduledThreadPoolExecutor c = new ScheduledThreadPoolExecutor(1);
    c.schedule(new Runnable() 
        @Override
        public void run() 
            final UncaughtExceptionHandler defaultHandler = Thread.getDefaultUncaughtExceptionHandler();
            Thread.setDefaultUncaughtExceptionHandler(new UncaughtExceptionHandler() 
                @Override
                public void uncaughtException(Thread paramThread, Throwable paramThrowable) 
                    // do my amazing stuff here 
                    System.err.println("Error!");
                    //then pass the job to the previous handler
                    defaultHandler.uncaughtException(paramThread, paramThrowable);
                
            );
        
    , 5, TimeUnit.SECONDS);

我将其安排在 5 秒后的原因是因为 Crashlytics 需要一些时间来设置他的东西。我正在使用这段代码,它运行良好。当然,如果您的应用程序在启动时崩溃,很抱歉,但没有自定义处理程序;)

【讨论】:

【参考方案6】:

我找到了 Fabric 2.10.1 的解决方案:

Thread.setDefaultUncaughtExceptionHandler(yourExceptionHandler)
Fabric.with(this, Crashlytics())

【讨论】:

以上是关于Crashlytics Android SDK - 自定义 UncaughtExceptionHandler的主要内容,如果未能解决你的问题,请参考以下文章

当用户更改首选项时如何在运行时禁用 Crashlytics/Fabric

在 iOS 应用中升级 SDK 后 Firebase Crashlytics 不显示日志

是否可以手动安装最新的 Firebase Crashlytics iOS SDK?

在针对 iOS 8.4 SDK 使用 Crashlytics 3.3.4 构建时,类型参数不能应用于非参数化类“NSDictionary”

是否可以在使用 Fabric / Crashlytics 启动时查看先前崩溃的堆栈跟踪?

使用健身房后,Crashlytics 在 android 上失败。 (得到“Crashlytics 已将提交二进制文件移到 Crashlytics.framework 目录之外......”错误)