在android开发中,经常会遇到程序后台出错的现象,虽然用户可能不会察觉到这种情况,但是作为一个开发者,还是需要及时收集这些信息,来改善代码程序,话不多说,我们直接进入主题。
获取crash信息
在Thread类中为我们提供了下面的方法:
当crash发生的时候,系统会回调UncaughtExceptionHandler的 uncaughtException方法,在该方法中,我们可以获取到对应的异常信息。
创建CrashHandler
首先我们需要实现一个UncaughtExceptionHandler对象,在它的uncaughtException方法中获取异常信息,并将其进行存储,然后调用Thread类的setUncaughtExceptionHandler方法将它设置为线程默认的异常处理器。
public class MyCrashHandler implements UncaughtExceptionHandler{
private static MyCrashHandler sMyCrashHandler = new MyCrashHandler();
private Context mContext;
public static MyCrashHandler getInstance() {
return sMyCrashHandler;
}
public void init(Context context) {
Thread.setDefaultUncaughtExceptionHandler(this);
mContext = context;
}
/**
* thread为未捕获异常的线程, e为未捕获的异常
*/
@Override
public void uncaughtException(Thread t, Throwable e) {
StringBuffer sb = new StringBuffer();
String time = new SimpleDateFormat("yyyy年MM月dd日HH时mm分ss秒").format(new Date(System.currentTimeMillis()));
Writer writer = new StringWriter();
PrintWriter printWriter = new PrintWriter(writer);
//收集当前的手机信息
PackageManager pm = mContext.getPackageManager();
try {
PackageInfo pi = pm.getPackageInfo(mContext.getPackageName(),PackageManager.GET_ACTIVITIES);
printWriter.print("app version: ");
printWriter.print(pi.versionName);
printWriter.print("-");
printWriter.println(pi.versionCode);
printWriter.print("OS VERSION: ");
printWriter.print(Build.VERSION.RELEASE);
printWriter.print("-");
printWriter.println(Build.VERSION.SDK_INT);
printWriter.print("制造商: ");
printWriter.println(Build.MANUFACTURER);
} catch (NameNotFoundException e1) {
e1.printStackTrace();
}
// 手机当前的异常信息
e.printStackTrace(printWriter);
printWriter.close();
String result = writer.toString();
sb.append(result);
// 写入异常信息到文件中
try {
long timestamp = System.currentTimeMillis();
String fileName = "crash_" + time + ".log";
File file = new File(Environment.getExternalStorageDirectory(),
fileName);
FileOutputStream fos = new FileOutputStream(file);
fos.write(sb.toString().getBytes());
fos.close();
} catch (Exception ex) {
Log.e("errorerrorerror","ex is :"+ex.toString());
}
// 使用 Toast 来显示异常信息
new Thread() {
@Override
public void run() {
Looper.prepare();
Toast.makeText(mContext, "sorry app happend error", Toast.LENGTH_LONG).show();
Looper.loop();
}
}.start();
}
}
需要添加写入sdcard的权限:
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
创建全局Application类,初始化MyCrashHandler
public class MyApplication extends Application {
@Override
public void onCreate() {
super.onCreate();
MyCrashHandler myCrashHandler = MyCrashHandler.getInstance();
myCrashHandler.init(this);
}
}
在AndroidManifest.xml中配置MyApplication
<application
android:allowBackup="true"
android:name=".MyApplication">
手动抛出运行时异常:
findViewById(R.id.idText).setOnClickListener(new OnClickListener() {
@Override
public void onClick(View arg0) {
throw new RuntimeException("我自己测试抛出一个异常.....");
}
});
此时运行该程序,点击按钮可以看到,系统提示出错了,并且也会在sdcard目录下创建文件,并且将错误信息写入。