定义CrashLog文件:如果有存储器,则将文件保存在存储器下。否则保存在data目录下。存储器不一定是SD卡,也可能是mount出来的一块存储空间(不是内存)。比如,小米3就没有SD卡。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文件后,退出。
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
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 mActivityList = new LinkedList();
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);
}
}