定义CrashLog文件:若是有存储器,则将文件保存在存储器下。不然保存在data目录下。存储器不必定是SD卡,也多是mount出来的一块存储空间(不是内存)。好比,小米3就没有SD卡。java
public class CrashLog { private static Context mContext; public static final String DIR_FOR_APP = "myApp"; public static final String FILE_NAME_FOR_CRASH__LOG = "crash.txt"; public static void setContext( Context aContext ) { mContext = aContext.getApplicationContext(); } public static void writeLog(String log) throws Exception { File dir = createFileDir(DIR_FOR_APP); File file = new File(dir.getPath(), FILE_NAME_FOR_CRASH__LOG); if(!file.exists()){ file.createNewFile(); } StringBuffer orgStr = new StringBuffer(); FileReader fr = new FileReader(file); int ch = 0; while((ch = fr.read()) != -1) { orgStr.append((char)ch); } fr.close(); Calendar c = Calendar.getInstance(); String time = String.format("%2d:", c.get(Calendar.HOUR))+ String.format("%2d:", c.get(Calendar.MINUTE))+ String.format("%2d", c.get(Calendar.SECOND))+" "; String str = orgStr.toString() + "\r\n" + time + log + "\r\n"; FileWriter fw = new FileWriter(file); fw.write(str); fw.close(); } public static void clearLog(){ String dirPath = getDirPath(DIR_FOR_APP); if( dirPath != null ) { File file = new File(FILE_NAME_FOR_CRASH__LOG); if(file.exists()){ file.delete(); } } } public static String getDirPath(String dirName){ String filePath = null; String state = Environment.getExternalStorageState(); if (state.equals(Environment.MEDIA_MOUNTED)) { // 若是有存储器,则返回存储器的路径 filePath = Environment.getExternalStorageDirectory() + File.separator + dirName; } else {// 不然返回data目录的路径 filePath = mContext.getCacheDir().getPath() + File.separator + dirName; } return filePath; } public static File createFileDir(String dirName) { String filePath = getDirPath(dirName); if( filePath == null ) { return null; } File destDir = new File(filePath); if (!destDir.exists()) { destDir.mkdirs(); } return destDir; } }
2. 定义CrashHandler异常捕获类:当程序抛出异常后,由CrashHandler先捕获。将异常堆栈信息和手机系统信息打印到手机制定位置的log文件后,退出。android
public class CrashHandler implements UncaughtExceptionHandler { private Context mContext; private static CrashHandler mInstance = null; // 系统默认的异常处理(默认状况下,系统会终止当前的异常程序) private UncaughtExceptionHandler mDefaultCrashHandler; private CrashHandler(Context c) { // 获取系统默认的异常处理器 mDefaultCrashHandler = Thread .getDefaultUncaughtExceptionHandler(); // 将当前实例设为系统默认的异常处理器 Thread.setDefaultUncaughtExceptionHandler(this); // 获取Context,方便内部使用 mContext = c.getApplicationContext(); } public synchronized static CrashHandler create(Context cxt) { if (mInstance == null) { mInstance = new CrashHandler(cxt); } return mInstance; } /** * 当UncaughtException发生时会回调该函数来处理 */ @Override public void uncaughtException(Thread thread, Throwable ex) { // TODO Auto-generated method stub StringBuffer logInfo = new StringBuffer(); logInfo.append("Exception: "); logInfo.append(ex.getMessage()); logInfo.append("\r\n"); logInfo.append(getStackMsg(ex)); logInfo.append("Phone informations:"); logInfo.append("\r\n"); try { logInfo.append(getPhoneInfo()); // 导出异常信息到存储器中 CrashLog.writeLog(logInfo.toString()); } catch (Exception e) { //忽略异常 } finally { // 若是系统提供了默认的异常处理器,则交给系统去结束程序, if (mDefaultCrashHandler != null) { mDefaultCrashHandler.uncaughtException(thread, ex); } else { MyApplication.getInstance().exit(); } } } private static String getStackMsg(Throwable e) { StringBuffer sb = new StringBuffer(); StackTraceElement[] stackArray = e.getStackTrace(); for (int i = 0; i < stackArray.length; i++) { StackTraceElement element = stackArray[i]; sb.append(element.toString() + "\r\n"); } return sb.toString(); } private String getPhoneInfo() throws NameNotFoundException { StringBuffer info = new StringBuffer(); // 应用的版本号 PackageManager pm = mContext.getPackageManager(); PackageInfo pi = pm.getPackageInfo(mContext.getPackageName(), PackageManager.GET_ACTIVITIES); info.append("App Version Name: "); info.append(pi.versionName); info.append("\r\n"); // android版本号 info.append("OS Version: "); info.append(Build.VERSION.RELEASE); info.append("_"); info.append(Build.VERSION.SDK_INT); info.append("\r\n"); // 手机制造商 info.append("Vendor: "); info.append(Build.MANUFACTURER); info.append("\r\n"); // 手机型号 info.append("Model: "); info.append(Build.MODEL); info.append("\r\n"); // cpu架构 info.append("CPU ABI: "); info.append(Build.CPU_ABI); info.append("\r\n"); return info.toString(); } }
3. 自定义Application类,初始化CrashLog和CrashHandler,并提供彻底退出应用的接口exit()。架构
public class MyApplication extends Application{ // 单例模式 private static MyApplication mAppInstance; // Activity容器 private List<Activity> mActivityList = new LinkedList<Activity>(); public MyApplication(){ } public static MyApplication getInstance() { if( mAppInstance == null ) { mAppInstance = new MyApplication(); } return mAppInstance; } // 每新建一个Activity,都要添加到容器中 public void addActivity(Activity a){ mActivityList.add(a); } // 遍历容器中全部Activity并finish public void exit(){ for (Activity activity : mActivityList) { activity.finish(); } System.exit(0); } @Override public void onCreate() { super.onCreate(); CrashLog.setContext(this); CrashHandler.create(this); } }