android框架搭建(一)-基本工具[log]的建立
2017-04-28 18:02
309 查看
android框架搭建(一)-基本工具[log]的建立
log 作为统一tag的日志输出,对于高质量的代码事非常重要的:
在开发中保持所有开发人员输出log格式一致便于阅读便于快速发现bug
由于log打印日志非常耗费CPU,所以程序在运行或者项目开发的不同阶段的时候只需要选择打印自己需要的那一部分日志,来降低CPU耗费
考虑线上安全,避免日志被非法抓取
保存错误信息到栈
话不多说上代码:
import android.content.Context; import android.content.Intent; import android.content.pm.PackageInfo; import android.content.pm.PackageManager; import android.content.pm.PackageManager.NameNotFoundException; import android.os.Build; import android.text.format.Time; import android.util.Log; 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.util.Properties; public class CrashHandler implements UncaughtExceptionHandler { /** Debug Log tag */ public static final String TAG = "CrashHandler"; /** * 是否开启日志输出,在Debug状态下开启, 在Release状态下关闭以提示程序性能 * */ public static final boolean DEBUG = false; /** 系统默认的UncaughtException处理类 */ private UncaughtExceptionHandler mDefaultHandler; /** CrashHandler实例 */ private static CrashHandler INSTANCE; /** 程序的Context对象 */ private Context mContext; /** 使用Properties来保存设备的信息和错误堆栈信息 */ private Properties mDeviceCrashInfo = new Properties(); private static final String VERSION_NAME = "versionName"; private static final String VERSION_CODE = "versionCode"; private static final String STACK_TRACE = "STACK_TRACE"; /** 错误报告文件的扩展名 */ private static final String CRASH_REPORTER_EXTENSION = ".cr"; /** 保证只有一个CrashHandler实例 */ private CrashHandler() { } /** 获取CrashHandler实例 ,单例模式 */ public static CrashHandler getInstance() { if (INSTANCE == null) { INSTANCE = new CrashHandler(); } return INSTANCE; } /** * 初始化,注册Context对象, 获取系统默认的UncaughtException处理器, 设置该CrashHandler为程序的默认处理器 * * @param ctx */ public void init(Context ctx) { mContext = ctx; mDefaultHandler = Thread.getDefaultUncaughtExceptionHandler(); Thread.setDefaultUncaughtExceptionHandler(this); } /** * 当UncaughtException发生时会转入该函数来处理 */ @Override public void uncaughtException(Thread thread, Throwable ex) { mContext.sendBroadcast(new Intent(IntentAction.EXIT_APPLICATION)); if ( mDefaultHandler != null) { handleException(ex); // 如果用户没有处理则让系统默认的异常处理器来处理 mDefaultHandler.uncaughtException(thread, ex); } else { // Sleep一会后结束程序 try { Thread.sleep(5000); } catch (InterruptedException e) { Log.e(TAG, "Error : ", e); } android.os.Process.killProcess(android.os.Process.myPid()); System.exit(10); } } /** * 自定义错误处理,收集错误信息 发送错误报告等操作均在此完成. 开发者可以根据自己的情况来自定义异常处理逻辑 * * @param ex * @return true:如果处理了该异常信息;否则返回false */ private boolean handleException(Throwable ex) { if (ex == null) { Log.w(TAG, "handleException --- ex==null"); return true; } final String msg = ex.getLocalizedMessage(); if (msg == null) { return false; } // 收集设备信息 collectCrashDeviceInfo(mContext); // 保存错误报告文件 saveCrashInfoToFile(ex); return true; } /** * 保存错误信息到文件中 * * @param ex * @return */ private String saveC 4000 rashInfoToFile(Throwable ex) { Writer info = new StringWriter(); PrintWriter printWriter = new PrintWriter(info); ex.printStackTrace(printWriter); Throwable cause = ex.getCause(); while (cause != null) { cause.printStackTrace(printWriter); cause = cause.getCause(); } String result = info.toString(); printWriter.close(); mDeviceCrashInfo.put("EXEPTION", ex.getLocalizedMessage()); mDeviceCrashInfo.put(STACK_TRACE, result); try { // long timestamp = System.currentTimeMillis(); Time t = new Time("GMT+8"); t.setToNow(); // 取得系统时间 int date = t.year * 10000 + (t.month + 1) * 100 + t.monthDay; int time = t.hour * 10000 + t.minute * 100 + t.second; String fileName = "crash-" + date + "-" + time + CRASH_REPORTER_EXTENSION; FileOutputStream trace = mContext.openFileOutput(fileName, Context.MODE_PRIVATE); mDeviceCrashInfo.store(trace, ""); trace.flush(); trace.close(); return fileName; } catch (Exception e) { Log.e(TAG, "an error occured while writing report file...", e); } return null; } /** * 收集程序崩溃的设备信息 * * @param ctx */ public void collectCrashDeviceInfo(Context ctx) { try { PackageManager pm = ctx.getPackageManager(); PackageInfo pi = pm.getPackageInfo(ctx.getPackageName(), PackageManager.GET_ACTIVITIES); if (pi != null) { mDeviceCrashInfo.put(VERSION_NAME, pi.versionName == null ? "not set" : pi.versionName); mDeviceCrashInfo.put(VERSION_CODE, "" + pi.versionCode); } } catch (NameNotFoundException e) { Log.e(TAG, "Error while collect package info", e); } // 使用反射来收集设备信息.在Build类中包含各种设备信息, // 例如: 系统版本号,设备生产商 等帮助调试程序的有用信息 // 具体信息请参考后面的截图 Field[] fields = Build.class.getDeclaredFields(); for (Field field : fields) { try { field.setAccessible(true); mDeviceCrashInfo.put(field.getName(), "" + field.get(null)); if (DEBUG) { Log.d(TAG, field.getName() + " : " + field.get(null)); } } catch (Exception e) { Log.e(TAG, "Error while collect crash info", e); } } } }
相关文章推荐
- Android在Eclipse工具搭建测试框架方式
- Struts2框架基本构建,Maven工具使用以及搭建私服,Hbernate框架构建以及连接mysql数据库
- J2EE项目系列(四)--SSM框架构建积分系统和基本商品检索系统(Spring+SpringMVC+MyBatis+Lucene+Redis+MAVEN)(2)建立商品数据库和Lucene的搭建
- Android实战(橘子娱乐)-首页(第一篇 MVP框架基本搭建和实现准备)
- Android第一讲——基本框架、环境搭建
- Android快速开发之——最常用的基本列表框架搭建
- android框架的基本搭建
- Android客户端基于XMPP的IM(openfire+asmack)的聊天工具之环境搭建及与服务器建立连接(一)
- android框架搭建——封装一个属于自己的数据存储工具类(SQLite篇)
- 使用DXUT建立基本框架
- 用开源工具ShowSlow搭建WEB前端性能测试度量框架
- 第6章 MVC基本工具 — 精通MVC 3 框架
- html5 Game开发系列文章之 三 搭建基本游戏框架(代码封装)
- Android 游戏开发----【搭建游戏开发框架】
- android 2D图形系统 skia框架基本分析(一)--以后整个skia调用关系图出来
- 【Android】在Android上使用OrmLite数据库框架 之 基本用法
- 精品教程--Android基本概念以及开发环境搭建
- Android开发环境的搭建之二 VMware虚拟工具安装
- 如何搭建android的开发环境 虚拟机和ubuntu的安装与建立编译条件
- 搭建Android开发环境与开发工具选择