在Android活动中记录未处理的异常 [英] Logging unhandled exceptions in Android Activity
问题描述
我创建了一个类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:
-
logError()
方法被调用多次,有时甚至被调用8-10次.查看日志,我可以看到它们几乎具有相同的时间戳. - 设备屏幕上显示一条消息"XXX应用程序已停止"(很好),但是关闭它后,该应用程序被挂起,我需要从应用程序设置屏幕上强制停止.
- 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. - 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屋!