在Android开发中经常会遇到各种各样的异常使程序闪退,每次的问题不尽相同,如果每次是链接电脑还可以通过log找到哪里的代码出错,可是有的时候闪退我们并不能很及时的捕获到异常,但是我们又想得到闪退时候的log日志,鉴于此一个Crash收集器显得大有用处了。
我们可以将异常存储在本地也可以上传到服务器。本地信息可以便于我们快速找到出现错误的地方,上传服务器便于我们对异常信息进行分类总结整理,从而能够能快速的分析解决问题。
- 异常的收集主要实现UncaughtExceptionHandler接口,具体看一下代码实现过程
1 | mDefaultCrashHandler=new Thread.UncaughtExceptionHandler(){ |
保存到本地调用saveException(ex)代码如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30/**
* 把错误保存起来,如果有sdCard,则保存到sdCard的缓存中,否则保存到内部存储的缓存中
* sdCard位置: /storage/emulated/0/Android/data/com.coder.someproject/cache/log/20151113_095811.log<br/>
* 内部存储位置:/data/data/com.coder.someproject/cache/log/20151113_180041.log
* @param ex
* @throws Exception
*/
private void saveException(Throwable ex) throws Exception {
File logDir = Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState())
? mContext.getExternalCacheDir()
:mContext.getCacheDir();
logDir = new File(logDir, "log");
if (!logDir.exists()) {
logDir.mkdir();
}
File logFile = new File(logDir, new SimpleDateFormat("yyyyMMdd_HHmmss", Locale.SIMPLIFIED_CHINESE).format(new Date()) + ".log");
Log.e("abc", "错误日记保存位置:" + logFile.getAbsolutePath());
try {
long current=System.currentTimeMillis();
String time=new SimpleDateFormat("yyyy-mm-dd HH:mm:ss").format(new Date(current));
PrintWriter pw=new PrintWriter(new BufferedWriter(new FileWriter(logFile)));
pw.println("time:"+time);
dumpPhoneInfo(pw);
pw.println();
ex.printStackTrace(pw);
pw.close();
} catch (IOException e) {
e.printStackTrace();
}
}为了便于我们追逐异常我们还需要知道当期应用使用手机的信息
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31/**
* 获取当前应用和手机的信息
* @param pw
*/
private void dumpPhoneInfo(PrintWriter pw) {
PackageManager pm=mContext.getPackageManager();
try {
PackageInfo pi=pm.getPackageInfo(mContext.getPackageName(),PackageManager.GET_ACTIVITIES);
pw.print("App Version:");
pw.print(pi.versionName);
pw.print("_");
pw.println(pi.versionCode);
//Android 版本号
pw.print("OS Version:");
pw.print(Build.VERSION.RELEASE);
pw.print("_");
pw.println(Build.VERSION.SDK_INT);
//手机制造商信息
pw.print("Vendor:");
pw.println(Build.MANUFACTURER);
//手机型号
pw.print("Model:");
pw.println(Build.MODEL);
//cup架构
pw.print("CPU ABI:");
pw.println(Build.CPU_ABI);
} catch (PackageManager.NameNotFoundException e) {
e.printStackTrace();
}
}这样一个Carsh收集工作就做好,然后在Applciaton中初始化就可以工作了
1
2
3
4
5public void onCreate() {
super.onCreate();
CrashHandler crashHandler=new CrashHandler();
crashHandler.init(this);
}
测试一下,我们自定义一个异常,然后查看我们本地收集到的异常信息
1
2
3
4
5
6
7
8button .setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
Toast.makeText(MainActivity.this,"button",Toast.LENGTH_SHORT);
throw new RuntimeException("自定义异常.....");
}
});
}本地捕获异常信息截图
异常捕获工具类放到Gists上了:Crash收集器