我已经集成了Firebase Crashlytics版本2.9.1来挖掘崩溃,以覆盖我的应用程序的性能和稳定性。
如果应用程序具有自己的UncaughtExceptionHandler,则不会在firebase crashlytics控制台上记录崩溃。
我的应用程序中有BaseActivity。在onCreate()方法中,我根据项目需求注册了自定义的UncaughtExceptionHandler。
无论何时由于任何原因导致应用程序崩溃,用户都应该被重定向到闪屏(MainActivity.java)。
public class BaseActivity extends FragmentActivity{
@Override
protected void onCreate(Bundle arg0) {
// Enable global crash handler.
Thread.setDefaultUncaughtExceptionHandler(handleAppCrash);
}
/***
* @Purpose Called when any crash occurs in the application.
***/
private Thread.UncaughtExceptionHandler handleAppCrash = new Thread.UncaughtExceptionHandler() {
@Override
public void uncaughtException(Thread thread, Throwable ex) {
Intent intent = new Intent(context, MainActivity.class); //redirect to Splash screen
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
context.startActivity(intent);
System.exit(0);
}
};
} 发布于 2020-10-05 14:46:33
对于最新的firebase crashlytics 17.x.x,他们在内容提供者内部设置了未捕获的异常处理程序,这样他们就不需要开发人员传递上下文并手动初始化。这样做是为了在应用程序启动时自动初始化firebase。因此,即使我们在Application类oncreate中设置了未捕获的异常处理程序,我们的实现也会覆盖firebase的异常处理程序,并且不会向firebase异常处理程序报告崩溃。
Fix:为了解决这个问题,我们必须编写一个自定义的内容提供者,并在我们的应用程序中将其优先级设置为最高。然后在内容提供者的oncreate中初始化未捕获的异常处理程序,而不是在应用程序类中进行初始化。这样,我们的将首先被初始化,并且不会覆盖firebase的。
发布于 2019-06-24 17:47:39
好的,我已经调查过这个问题了。
您不应该在BaseActivity内部创建自定义异常处理程序。最好在你的Application类中完成。在BaseActivity的情况下,您将在每次启动新活动时获得一个新的处理程序,这将扩展您的BaseActivity。
因此,在应用程序类onCreate()方法中,您可以获得默认应用程序处理程序
val defaultExceptionHandler = Thread.getDefaultUncaughtExceptionHandler()在我的例子中,它是一个
com.crashlytics.android.core.CrashlyticsUncaughtExceptionHandler这个"defaultExceptionHandler“用于向firebase发送正确的错误。然后,您可以创建自己的异常处理程序,但需要在此处保存此"defaultExceptionHandler“。
class DefaultExceptionHandler (private val defaultExceptionHandler:Thread.UncaughtExceptionHandler?) : Thread.UncaughtExceptionHandler {
override fun uncaughtException(thread: Thread, ex: Throwable) {
try {
// here you restore your activity and do other things
// and of course you deal with defaultExceptionHandler
// without it firebase will not work
defaultExceptionHandler?.uncaughtException(thread, ex)
// only after firebase dealed with an exception, you can exit
System.exit(0)
} catch (e: IOException) {
// just catch
}
}
}最后,firebase会在你需要的时候告诉你崩溃了。应用程序onCreate()示例
override fun onCreate() {
super.onCreate()
Fabric.with(this, Crashlytics())
val defaultExceptionHandler = Thread.getDefaultUncaughtExceptionHandler()
val customExceptionHandler = DefaultExceptionHandler(defaultExceptionHandler)
Thread.setDefaultUncaughtExceptionHandler(customExceptionHandler)
}发布于 2020-10-31 02:31:10
我在我的应用中也遇到了同样的问题。根据@niyas的建议,我也使用了相同的解决方案,它对我来说工作得很好。Firebase使用内容提供程序初始化firebase crashlytics sdk及其未捕获的异常处理程序。因此,如果您在自定义内容提供程序中注册了未捕获的异常处理程序,其优先级高于firebase提供程序。则接收对处理程序的回调的顺序颠倒。首先,回调将发送到Firebase处理程序,然后再发送到您的处理程序。通过这种方式,firebase收集崩溃的堆栈跟踪,您还可以获得回调处理程序来重新启动应用程序/或任何其他用例。我在github上找到了这个解决方案,这是a link!
代码片段:
<application>
...
<!-- Firebase SDK initOrder is 100. Higher order init first -->
<provider
android:name=".UncaughtExceptionHandlerContentProvider"
android:authorities="${applicationId}"
android:exported="false"
android:initOrder="101"
android:grantUriPermissions="false" />
...
</application>
public class UncaughtExceptionHandlerContentProvider extends ContentProvider {
@Override
public boolean onCreate() {
MyCustomCrashHandler myHandler = new MyCustomCrashHandler(Thread.getDefaultUncaughtExceptionHandler());
Thread.setDefaultUncaughtExceptionHandler(myHandler);
return true;
}
@Nullable
@Override
public Cursor query(@NonNull Uri uri, @Nullable String[] projection, @Nullable String selection, @Nullable String[] selectionArgs, @Nullable String sortOrder) { return null; }
@Nullable
@Override
public String getType(@NonNull Uri uri) { return null; }
@Nullable
@Override
public Uri insert(@NonNull Uri uri, @Nullable ContentValues values) { return null; }
@Override
public int delete(@NonNull Uri uri, @Nullable String selection, @Nullable String[] selectionArgs) { return 0; }
@Override
public int update(@NonNull Uri uri, @Nullable ContentValues values, @Nullable String selection, @Nullable String[] selectionArgs) { return 0; }
}
public class MyCustomCrashHandler implements UncaughtExceptionHandler {
@Nullable
private final UncaughtExceptionHandler defaultHandler;
public MyCustomCrashHandler(@Nullable UncaughtExceptionHandler defaultHandler)(){
this.defaultHandler = defaultHandler;
}
@Override
public void uncaughtException(@NonNull Thread thread, @NonNull Throwable ex) {
// We are now safely being called after Crashlytics does its own thing.
// Whoever is the last handler on Thread.getDefaultUncaughtExceptionHandler() will execute first on uncaught exceptions.
// Firebase Crashlytics will handle its own behavior first before calling ours in its own 'finally' block.
// You can choose to propagate upwards (it will kill the app by default) or do your own thing and propagate if needed.
try {
//do your own thing.
} catch (Exception e) {
e.printStackTrace();
} finally {
if (defaultHandler != null) {
defaultHandler.uncaughtException(thread, ex)
// propagate upwards. With this workaround (and also without any other similar UncaughtExceptionHandler based on ContentProvider),
// defaultHandler should now be an instance of com.android.internal.os.RuntimeInit.KillApplicationHandler
// hence properly killing the app via framework calls.
}
}
}https://stackoverflow.com/questions/50585187
复制相似问题