android 异常收集
来源:互联网 发布:python sleep函数 编辑:程序博客网 时间:2024/05/17 19:22
当开发了一个APP,发布出去之后难免会碰到系统异常的情况,而且大多数的异常是不可重现的。经常遇到的情况就是平台迁移之后,数据与原来存在差异,比如说实际情况种
的数据和开发和测试不一样。还有就是测试覆盖面不全,市面上的手机型号那么多,而有的公司并不会为没款手机都适配,跑不同的手机出现异常在所难免。这个时候如果出现
了异常调试起来时比较麻烦的,因为出现异常的环境不一定就能重现出来。
这里主要总结一下开发中用到的异常捕获和调试方法,不同于开发中使用的logcat。思路和原理都很简单,就是当应用发生 异常的时候,可以把异常信息收集并保存起来,我这
里是把它保存到了一个固定目录下的文件中,出现异常时可以通过异常记录文件跟踪定位异常,分析出错原因。
捕获异常的方法是通过实现UncaughtExceptionHandler接口,当异常发生的时候,会回调uncaughtException()方法,在此方法中完成我们需要处理的工作,此处仅把出错信息
保存到固定目录中。
1.首先定义一个自己的异常处理类,实现UncaughtExceptionHandler接口,代码如下:
public class ExceptionHandler implements Thread.UncaughtExceptionHandler {private static ExceptionHandler instance = new ExceptionHandler();private Context context;private String infoPath = "/ErrorLog/";private Thread.UncaughtExceptionHandler defaultHandler;private Map<String, String> devInfos = new HashMap<String, String>();private DateFormat df = new SimpleDateFormat("yyyyMMddHHmmss", Locale.getDefault());public static ExceptionHandler getInstance() {return instance;}public void setCustomCrashHanler(Context ctx) {context = ctx;defaultHandler = Thread.getDefaultUncaughtExceptionHandler();Thread.setDefaultUncaughtExceptionHandler(this);}/** * @name uncaughtException(Thread thread, Throwable ex) * @description 当发生UncaughtException时会回调此函数 * @param thread 发生异常的线程 * @param ex 抛出的异常 * @return void */@Overridepublic void uncaughtException(Thread thread, Throwable ex) {boolean isDone = doException(ex);if (!isDone && defaultHandler != null) {// 如果用户没有处理则让系统默认的异常处理器来处理defaultHandler.uncaughtException(thread, ex);} else {// 如果自己处理了异常,则不会弹出错误对话框,则需要手动退出apptry {Thread.sleep(3000);} catch (InterruptedException e) {}}android.os.Process.killProcess(android.os.Process.myPid());System.exit(0);}/** * @name doException(Throwable ex) * @description 处理异常 * @param ex 抛出的异常 * @return 异常处理标志 */private boolean doException(Throwable ex) {if (ex == null) {return true;}new Thread() { @Override public void run() { Looper.prepare(); Toast.makeText(context, "程序出现错误退出!", Toast.LENGTH_LONG).show(); Looper.loop(); } }.start(); collectDeviceInfo(context);saveExceptionToFile(ex);return true;}/** * @name collectDeviceInfo(Context ctx) * @description 收集必须的设备信息 * @param ctx * @return void */public void collectDeviceInfo(Context ctx) {try {PackageManager pm = ctx.getPackageManager();PackageInfo pi = pm.getPackageInfo(ctx.getPackageName(), PackageManager.GET_ACTIVITIES);if (pi != null) {devInfos.put("versionName", pi.versionName);devInfos.put("versionCode", "" + pi.versionCode);devInfos.put("MODEL", "" + Build.MODEL);devInfos.put("SDK_INT", "" + Build.VERSION.SDK_INT);devInfos.put("PRODUCT", "" + Build.PRODUCT);devInfos.put("TIME", "" + getCurrentTime());}} catch (NameNotFoundException e) {}Field[] fields = Build.class.getDeclaredFields();for (Field field : fields) {try {field.setAccessible(true);devInfos.put(field.getName(), field.get(null).toString());} catch (Exception e) {}}}/** * @name saveExceptionToFile(Throwable ex) * @description 保存异常信息到文件中 * @param ex 抛出的异常 * @return void */private void saveExceptionToFile(Throwable ex) {StringBuffer sb = new StringBuffer();for (Map.Entry<String, String> entry : devInfos.entrySet()) {String key = entry.getKey();String value = entry.getValue();sb.append(key + "=" + value + "\n");}Writer writer = new StringWriter();PrintWriter printWriter = new PrintWriter(writer);ex.printStackTrace(printWriter);Throwable cause = ex.getCause();while (cause != null) {cause.printStackTrace(printWriter);cause = cause.getCause();}printWriter.close();String result = writer.toString();sb.append(result);try {String time = df.format(new Date());String fileName = time + ".txt";if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {String path = Environment.getExternalStorageDirectory() + infoPath;File dir = new File(path);if (!dir.exists()) {dir.mkdirs();}FileOutputStream fos = new FileOutputStream(path + fileName);fos.write(sb.toString().getBytes());fos.close();}} catch (Exception e) {}}/** * @name getCurrentTime() * @description 获取当前时间 * @param void * @return 当前时间 */public static String getCurrentTime() {SimpleDateFormat sdf = null;sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");String CurrentTime = sdf.format(new Date());return CurrentTime;}}
2.在自定义Application初始化异常捕获对象,并设置异常出现是处理的对象:
/** * @name MyApplication * @description 自定义Application * @author cold * @date 2016.05.18 15:30 * @copyright */public class MyApplication extends Application {@Overridepublic void onCreate() {super.onCreate();ExceptionHandler mCustomCrashHandler = ExceptionHandler.getInstance();mCustomCrashHandler.setCustomCrashHanler(this);}}
3.在MainActivity里模拟出现空指针的异常
public class MainActivity extends Activity {private Button btnTest = null;private Button btnError = null;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);btnTest = (Button)findViewById(R.id.btn_test);btnTest.setOnClickListener(listener);}private OnClickListener listener = new OnClickListener() {@Overridepublic void onClick(View v) {// TODO Auto-generated method stubbtnError.setText("error");}};}代码中btnError并未初始化,所以会报出空指针异常。
4.当出现异常时,可以查看/storage/sdcard0/ErrorLog目录下的异常文件,根据此文件分析异常原因:
文件内容截取:
java.lang.NullPointerExceptionat com.example.exceptiontest.MainActivity$1.onClick(MainActivity.java:26)at android.view.View.performClick(View.java:4496)at android.view.View$PerformClick.run(View.java:18603)at android.os.Handler.handleCallback(Handler.java:733)at android.os.Handler.dispatchMessage(Handler.java:95)at android.os.Looper.loop(Looper.java:136)at android.app.ActivityThread.main(ActivityThread.java:5426)at java.lang.reflect.Method.invokeNative(Native Method)at java.lang.reflect.Method.invoke(Method.java:515)at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1268)at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1084)at dalvik.system.NativeStart.main(Native Method)
可以看出这和我们使用logcat调试一样,只不过是多了一步文件存储的过程。
4.需要在AndroidManifest.xml中添加sd卡权限
<uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS" /> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
例子代码:
点击打开链接
0 0
- Android错误异常收集
- Android错误异常收集
- android 异常收集
- Android一点 异常收集
- android 异常收集
- Android异常收集
- Android异常收集
- android 异常捕获系统收集
- Android程序异常信息收集
- android 控件错误异常收集
- Android程序崩溃异常收集框架
- android开发异常信息收集程序代码
- Android程序崩溃异常收集框架
- Android 代码崩溃异常收集整理
- android异常收集- java.lang.NumberFormatException
- Android 异常错误收集和修复
- android自定义异常日志收集器
- 异常收集
- just 笔记s for network(持续loading)
- 正则表达式:Pattern,Matcher
- 搭建个人知识管理库
- 漫谈Java加密技术(三)
- 计算机图形学(二)输出图元_20_章节总结_程序展示_蜗形线、心形线、螺旋线
- android 异常收集
- swift总结
- jquery 动态实现进度条
- Windows安装多个mysql数据库
- li标签中,img居中显示
- 《JavaScript详解》学习笔记
- Merge Two Sorted Lists 归并list
- Fresco:SimpleDraweeView如何显示并加载图片
- Zend Framework 2.0的Mvc结构及启动流程分析