UncaughtExceptionHandler捕捉异常,保存至SD卡中
利用UncaughtExceptionHandler类,对程序的异常进行捕捉,并保存至SD卡中。
1、UncaughtExceptionHandler的子类实现
1 import java.io.BufferedReader; 2 import java.io.File; 3 import java.io.FileInputStream; 4 import java.io.FileNotFoundException; 5 import java.io.FileOutputStream; 6 import java.io.FileReader; 7 import java.io.IOException; 8 import java.io.PrintWriter; 9 import java.io.StringWriter; 10 import java.io.Writer; 11 import java.lang.Thread.UncaughtExceptionHandler; 12 import java.text.SimpleDateFormat; 13 import java.util.Date; 14 import java.util.Timer; 15 import java.util.TimerTask; 16 17 import android.content.Context; 18 19 public class SaveException implements UncaughtExceptionHandler { 20 21 private Context mContext; 22 private Thread.UncaughtExceptionHandler defaultExceptionHandler; 23 private static SaveException mException; 24 25 public static final String SDPATH = "/sdcard/RecordException/";// 存放位置 26 public static String fileName = "fenceEx.log"; 27 28 private SaveException() { 29 } 30 31 public static SaveException getInstance() { 32 if (mException == null) { 33 mException = new SaveException(); 34 } 35 return mException; 36 } 37 38 public void init(Context context) { 39 mContext = context; 40 defaultExceptionHandler = Thread.getDefaultUncaughtExceptionHandler(); 41 Thread.setDefaultUncaughtExceptionHandler(this); 42 } 43 44 @Override 45 public void uncaughtException(Thread thread, Throwable ex) { 46 47 if (!handleException(thread, ex) && defaultExceptionHandler != null) { 48 defaultExceptionHandler.uncaughtException(thread, ex); 49 } 50 } 51 52 53 private boolean handleException(Thread thread, Throwable ex) { 54 StringBuilder sb = new StringBuilder(); 55 56 long startTimer = System.currentTimeMillis(); 57 SimpleDateFormat formatter = new SimpleDateFormat("yyyy年MM月dd日 HH:mm:ss "); 58 Date firstDate = new Date(System.currentTimeMillis()); // 第一次创建文件,也就是开始日期 59 String str = formatter.format(firstDate); 60 61 sb.append("\n"); 62 sb.append(str+"----------------------------->"); // 把当前的日期写入到字符串中 63 sb.append("\n"); 64 65 Writer writer = new StringWriter(); 66 PrintWriter pw = new PrintWriter(writer); 67 68 ex.printStackTrace(pw); 69 70 String errorresult = writer.toString(); 71 sb.append(errorresult); 72 sb.append("\n"); 73 try { 74 File fileDir = new File(SDPATH); 75 // File fileDir = new File("/sdcard/com.ebank/EBank/"); 76 if (!fileDir.exists()) { 77 fileDir.mkdirs(); 78 } 79 80 File files = new File(fileDir, fileName); 81 if (!files.exists()) { 82 files.createNewFile(); 83 } 84 FileOutputStream fileOutputStream = new FileOutputStream(files, true); 85 fileOutputStream.write(sb.toString().getBytes()); 86 fileOutputStream.close(); 87 88 // 文件大小限制在1M,超过1M自动删除 89 FileInputStream fileInputStream = new FileInputStream(files); 90 int sizeK = fileInputStream.available() / 1024; // 单位是KB 91 int totalSize = 2 * 1024; 92 if (sizeK > totalSize) { 93 boolean b = files.delete(); 94 if (b) { // 删除成功,重新创建一个文件 95 @SuppressWarnings("unused") 96 File filesTwo = new File(fileDir, "fenceEx.log"); 97 if (!files.exists()) { 98 files.createNewFile(); 99 } 100 } else { 101 // 删除失败 102 FileOutputStream fileOutputStream2 = new FileOutputStream(files); 103 fileOutputStream2.write(" ".getBytes()); // 写入一个空格进去 104 } 105 } 106 // 文件保存7天,过了7天自动删除 107 FileReader fileReader = new FileReader(files); 108 BufferedReader bufferedReader = new BufferedReader(fileReader); 109 String firstLine = bufferedReader.readLine(); 110 long startTimerFile = Long.valueOf(firstLine.trim()); // 类型转换 111 long endTimer = System.currentTimeMillis(); 112 long totalDay = 24 * 60 * 60 * 1000 * 7; 113 final File f = files; 114 TimerTask timerTask = new TimerTask() { 115 @Override 116 public void run() { 117 try { 118 boolean n = f.delete(); 119 if (n) { 120 File fileDirs = new File("/data/data/com.ebank/Ebank/"); 121 if (!fileDirs.exists()) { 122 fileDirs.mkdirs(); 123 } 124 File filess = new File(fileDirs, "ebank.log"); 125 if (!filess.exists()) { 126 filess.createNewFile(); 127 } 128 } else { 129 // 删除失败 130 FileOutputStream fileOutputStream2 = new FileOutputStream(f); 131 fileOutputStream2.write(" ".getBytes()); // 写入一个空格进去 132 } 133 } catch (FileNotFoundException e) { 134 e.printStackTrace(); 135 } catch (IOException e) { 136 e.printStackTrace(); 137 } 138 } 139 }; 140 141 // 定时器类的对象 142 Timer timer = new Timer(); 143 if ((endTimer - startTimerFile) >= totalDay) { 144 timer.schedule(timerTask, 1); // 7天后执行 145 } 146 } catch (Exception e) { 147 e.printStackTrace(); 148 } 149 150 defaultExceptionHandler.uncaughtException(thread, ex); 151 return true; 152 } 153 }
2、在Application子类中初始
1 public class MyApplication extends Application { 2 public void onCreate() { 3 mInstance = this; 4 Engine_UserData.getInstance(this); 5 Engine_MapData.getInstance(this); 6 7 SaveException sException = SaveException.getInstance(); 8 sException.init(getApplicationContext()); 9 10 super.onCreate(); 11 } 12 }
ps:记得在AndroidManifest.xml文件中对MyApplication进行注册:
<application
android:name="com.xxxx.MyApplication"
........
/>
那么当你的应用在没有连接eclipse下也可以看到异常信息了。