在Android活动中记录未处理的异常 [英] Logging unhandled exceptions in Android Activity

查看:107
本文介绍了在Android活动中记录未处理的异常的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我创建了一个类BaseActivity extends AppCompatActivity,我在Android应用中的所有Activites都将从该类继承.

I have created a class BaseActivity extends AppCompatActivity from which all my Activites in an Android App are inheriting.

在此类中,我打算捕获所有未处理的异常,因此可以将它们写入本地SQLite数据库,以供以后检查/发送到远程服务器.

In this class I intended to catch all unhandled exceptions, so I can write them to a local SQLite database for later inspection / sending to remote server.

下面我附上完整的课程代码:

Below I attach entire class code:

public class BaseActivity extends AppCompatActivity {

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    final Thread.UncaughtExceptionHandler defaultHandler = Thread.getDefaultUncaughtExceptionHandler();

    Thread.setDefaultUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() {
        @Override
        public void uncaughtException(Thread paramThread, Throwable paramThrowable) {
            Log.e("Uncaught Exception", paramThrowable.getMessage());
            logError(paramThrowable);
            defaultHandler.uncaughtException(paramThread, paramThrowable);
        }
    });
}

private void logError(final Throwable paramThrowable){
    try {
        ApplicationError error = new ApplicationError();

        String stackTrace = "";
        for (int i = 0; i < paramThrowable.getStackTrace().length; i++) {
            stackTrace += paramThrowable.getStackTrace()[i].toString() + "\n";
        }

        Throwable tmp = paramThrowable;
        int j = 0;
        while ((tmp = tmp.getCause()) != null && j < 5) {
            j++;
            stackTrace += "Coused by:\n";
            for (int i = 0; i < tmp.getStackTrace().length; i++) {
                stackTrace += tmp.getStackTrace()[i].toString() + "\n";
            }
        }

        Log.e("Saving error...", "");

        String deviceInfo = "";
        deviceInfo += "OS version: " + System.getProperty("os.version") + "\n";
        deviceInfo += "API level: " + Build.VERSION.SDK_INT + "\n";
        deviceInfo += "Manufacturer: " + Build.MANUFACTURER + "\n";
        deviceInfo += "Device: " + Build.DEVICE + "\n";
        deviceInfo += "Model: " + Build.MODEL + "\n";
        deviceInfo += "Product: " + Build.PRODUCT + "\n";

        error.mDeviceInfo = deviceInfo;
        error.mErrorMessage = paramThrowable.getMessage();
        error.mStackTrace = stackTrace;

        error.save();

        Log.e("Saved error:", error.mErrorMessage + "\n" + error.mStackTrace);
    }catch(Exception e){

    }
}

}

为澄清起见: ApplicationError只是一个模型类,它处理使用DBFlow保存到数据库的情况.

For clarification: ApplicationError is just a model class which handles saving to the database using DBFlow.

问题

每次在活动中发生未处理的异常(无关紧要)时,都会发生两种奇怪的事情:

Each time an unhandled exception occurs (doesn't matter what it is) in an activity two weird things happen:

  1. logError()方法被调用多次,有时甚至被调用8-10次.查看日志,我可以看到它们几乎具有相同的时间戳.
  2. 设备屏幕上显示一条消息"XXX应用程序已停止"(很好),但是关闭它后,该应用程序被挂起,我需要从应用程序设置屏幕上强制停止.
  1. The logError() method is called more than once, sometimes even 8-10 times. Looking at logs I can see they have almost the same timestamp.
  2. A message 'XXX Application has stopped" is shown on a device screen (which is fine), but after closing it the application is hanged and I need to force-stop from application settings screen.

有人可以帮我吗?还是有解决这个问题的更好方法?

Can anyone help me with this? Or is there a better approach to the problem?

推荐答案

我终于在

I managed to finally solve this with help of AAG's answer.

@AAG,您是对的,每次在任何活动中调用onCreate()方法时,都会添加异常处理程序.

@AAG you were right, the exception handler was being added each time an onCreate() method in any activity was called.

@AAG但是您不使用defaultHandler是错误的.我必须使用它,以便Android能够正确处理应用程序崩溃.

@AAG But you were wrong about not using defaultHandler. I have to use it, for Android to properly handle application crash.

感谢您的帮助!

这是固定代码:

public class BaseActivity extends AppCompatActivity {

    public static Context applicationContext = null;
    public static Thread.UncaughtExceptionHandler defaultHandler = null;
    public static Thread.UncaughtExceptionHandler exceptionHandler = null;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        if(defaultHandler == null){
            defaultHandler = Thread.getDefaultUncaughtExceptionHandler();
        }

        if(applicationContext == null){
            applicationContext = getApplicationContext();
        }

        if(exceptionHandler == null){
            exceptionHandler = new Thread.UncaughtExceptionHandler() {
                @Override
                public void uncaughtException(Thread paramThread, Throwable paramThrowable) {
                    Log.e("Uncaught Exception", paramThrowable.getMessage());
                    logError(paramThrowable);
                    defaultHandler.uncaughtException(paramThread, paramThrowable);

                }
            };

            Thread.setDefaultUncaughtExceptionHandler(exceptionHandler);
        }
    }

    private static void logError(final Throwable paramThrowable){
        try {
            ApplicationError error = new ApplicationError();

            String stackTrace = "";
            for (int i = 0; i < paramThrowable.getStackTrace().length; i++) {
                stackTrace += paramThrowable.getStackTrace()[i].toString() + "\n";
            }

            Log.e("Saving error...", "");

            Throwable tmp = paramThrowable;
            int j = 0;
            while ((tmp = tmp.getCause()) != null && j < 5) {
                j++;
                stackTrace += "Coused by:\n";
                for (int i = 0; i < tmp.getStackTrace().length; i++) {
                    stackTrace += tmp.getStackTrace()[i].toString() + "\n";
                }
            }

            String deviceInfo = "";
            deviceInfo += "OS version: " + System.getProperty("os.version") + "\n";
            deviceInfo += "API level: " + Build.VERSION.SDK_INT + "\n";
            deviceInfo += "Manufacturer: " + Build.MANUFACTURER + "\n";
            deviceInfo += "Device: " + Build.DEVICE + "\n";
            deviceInfo += "Model: " + Build.MODEL + "\n";
            deviceInfo += "Product: " + Build.PRODUCT + "\n";

            error.mDeviceInfo = deviceInfo;
            error.mErrorMessage = paramThrowable.getMessage();
            error.mStackTrace = stackTrace;

            error.save();

            Log.e("Saved error:", error.mErrorMessage + "\n" + error.mStackTrace);
        }catch(Exception e){

        }
    }

}

这篇关于在Android活动中记录未处理的异常的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆