android基础知识24:Android中处理崩溃异常
大家都知道,现在安装Android系统的手机版本和设备千差万别,在模拟器上运行良好的程序安装到某款手机上说不定就出现崩溃的现象,开发者个人不可能购买所有设备逐个调试,所以在程序发布出去之后,如果出现了崩溃现象,开发者应该及时获取在该设备上导致崩溃的信息,这对于下一个版本的bug修复帮助极大,所以今天就来介绍一下如何在程序崩溃的情况下收集相关的设备参数信息和具体的异常信息,并发送这些信息到服务器供开发者分析和调试程序。
1、重启activity
通常情况下,如果Android应用出现未处理的异常,会出现下面类似的对话框,然后强制退出该应用:
如果你想改变这种缺省的行为,比如出现未处理异常时显示自定义对话框,或是重启该应用,可以使用下面步骤重定义Android全局异常处理事件。
1. 实现Thread.UncaughtExceptionHandler 接口
一般可以通过派生Application类并实现Thread.UncaughtExceptionHandler 方法:
[java]
public class GNavigatorApplication extends Application
implements Thread.UncaughtExceptionHandler {
...
}
public class GNavigatorApplication extends Application
implements Thread.UncaughtExceptionHandler {
...
} 2. 定义Thread.UncaughtExceptionHandler方法
比如重启某个Activity
[java]
public void uncaughtException(Thread thread, Throwable ex) {
Intent intent = new Intent(this, GNavigatorActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
}
public void uncaughtException(Thread thread, Throwable ex) {
Intent intent = new Intent(this, GNavigatorActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
} 3. 重置缺省的Exception处理函数,比如可以在OnCreate方法重设Exception处理方法。
[java]
@Override
public void onCreate() {
...
Thread.setDefaultUncaughtExceptionHandler(this);
}
@Override
public void onCreate() {
...
Thread.setDefaultUncaughtExceptionHandler(this);
} 这样在应用中出现未处理异常时,会自动重启应用,而不会出现Force Close对话框。
2、获取异常信息并上传至服务器
我们先建立一个crash项目,项目结构如图:
在MainActivity.java代码中,代码是这样写的:
[java]
package com.scott.crash;
import android.app.Activity;
import android.os.Bundle;
public class MainActivity extends Activity {
private String s;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
System.out.println(s.equals("any string"));
}
}
package com.scott.crash;
import android.app.Activity;
import android.os.Bundle;
public class MainActivity extends Activity {
private String s;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
System.out.println(s.equals("any string"));
}
} 我们在这里故意制造了一个潜在的运行期异常,当我们运行程序时就会出现以下界面:
遇到软件没有捕获的异常之后,系统会弹出这个默认的强制关闭对话框。
我们当然不希望用户看到这种现象,简直是对用户心灵上的打击,而且对我们的bug的修复也是毫无帮助的。我们需要的是软件有一个全局的异常捕获器,当出现一个我们没有发现的异常时,捕获这个异常,并且将异常信息记录下来,上传到服务器公开发这分析出现异常的具体原因。
接下来我们就来实现这一机制,不过首先我们还是来了解以下两个类:android.app.Application和java.lang.Thread.UncaughtExceptionHandler。
Application:用来管理应用程序的全局状态。在应用程序启动时Application会首先创建,然后才会根据情况(Intent)来启动相应的Activity和Service。本示例中将在自定义加强版的Application中注册未捕获异常处理器。
Thread.UncaughtExceptionHandler:线程未捕获异常处理器,用来处理未捕获异常。如果程序出现了未捕获异常,默认会弹出系统中强制关闭对话框。我们需要实现此接口,并注册为程序中默认未捕获异常处理。这样当未捕获异常发生时,就可以做一些个性化的异常处理操作。
大家刚才在项目的结构图中看到的CrashHandler.java实现了Thread.UncaughtExceptionHandler,使我们用来处理未捕获异常的主要成员,代码如下:
[java]
package com.scott.crash;
import java.io.File;
import java.io.FileOutputStream;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.io.Writer;
import java.lang.Thread.UncaughtExceptionHandler;
import java.lang.reflect.Field;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import android.content.Context;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
import android.os.Build;
import android.os.Environment;
import android.os.Looper;
import android.util.Log;
import android.widget.Toast;
/**
* UncaughtException处理类,当程序发生Uncaught异常的时候,有该类来接管程序,并记录发送错误报告.
*
* @author user
*
*/
public class CrashHandler implements UncaughtExceptionHandler {
public static final String
补充:移动开发 , Android ,