package com.ryan.test.crash; import java.io.File; import java.io.FileOutputStream; import java.lang.Thread.UncaughtExceptionHandler; import android.content.Context; import android.os.Environment; import android.os.Looper; public class AppLogHandler implements UncaughtExceptionHandler { public static final boolean DEBUG = true; public static final String AGR_LOG_DIRECOTORY = "agrlog"; private Thread.UncaughtExceptionHandler mDefaultHandler; private static AppLogHandler instance; private AppLogHandler() { } public static AppLogHandler getInstance() { if (instance == null) { instance = new AppLogHandler(); } return instance; } public void init(Context context) { mDefaultHandler = Thread.getDefaultUncaughtExceptionHandler(); Thread.setDefaultUncaughtExceptionHandler(this); } @Override public void uncaughtException(Thread thread, Throwable ex) { if (!handleException(ex) && mDefaultHandler != null) { mDefaultHandler.uncaughtException(thread, ex); } else { try { Thread.sleep(3000); } catch (Exception e) { e.printStackTrace(); } android.os.Process.killProcess(android.os.Process.myPid()); System.exit(10); } } private boolean handleException(final Throwable ex) { if (DEBUG) { if (ex == null) { return false; } final StackTraceElement[] stack = ex.getStackTrace(); final String message = ex.getMessage(); new Thread() { @Override public void run() { Looper.prepare(); createLogDirectory(); String fileName = AGR_LOG_DIRECOTORY + "/crash-" + System.currentTimeMillis() + ".log"; File file = new File( Environment.getExternalStorageDirectory(), fileName); try { FileOutputStream fos = new FileOutputStream(file, true); fos.write(message.getBytes()); for (int i = 0; i < stack.length; i++) { fos.write(stack[i].toString().getBytes()); } fos.flush(); fos.close(); } catch (Exception e) { } Looper.loop(); } }.start(); } return false; } private void createLogDirectory() { File file = new File(Environment.getExternalStorageDirectory(), AGR_LOG_DIRECOTORY); try { if (!file.exists() || !file.isDirectory()) { file.mkdir(); } } catch (Exception e) { e.printStackTrace(); } } }
2.为了读取Logcat的信息并保存到SD卡中,必须添加对应的权限:
<uses-permission android:name="android.permission.READ_LOGS" /> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
3.新建MyApplication类继承自Application,在应用启动时开启对导致程序意外退出的错误的捕获:
import com.ryan.test.crash.AppLogHandler; import android.app.Application; public class MyApplication extends Application{ @Override public void onCreate() { super.onCreate(); AppLogHandler appLogHandler = AppLogHandler.getInstance(); appLogHandler.init(getApplicationContext()); } }
4.为了使MyApplication生效,必须修改AndroidMenifest.xml文件:
<application android:name="com.ryan.test.MyApplication" android:allowBackup="true" android:icon="@drawable/ic_launcher" android:label="@string/app_name" android:theme="@android:style/Theme.NoTitleBar"> <!-- 省略其他信息 --> </application>