代码如下:
package com.example.crashhandler;
import java.io.File;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.RandomAccessFile;
import java.io.StringWriter;
import java.io.Writer;
import java.lang.Thread.UncaughtExceptionHandler;
import java.lang.reflect.Field;
import android.annotation.SuppressLint;
import android.os.Build;
import android.os.Environment;
/**
* 异常管理器
* @author Administrator
*
*/
public class ICrashMgr {
private static ICrashMgr ins=new ICrashMgr();
private ICrashMgr(){};
public static ICrashMgr getInstance()
{
return ins;
}
public void init()
{
mDefaultHandler=Thread.getDefaultUncaughtExceptionHandler();//获取系统默认的UncaughtException处理器
Thread.setDefaultUncaughtExceptionHandler(mICrashHandler);//重新设置该CrashHandler为程序的默认处理器
}
private UncaughtExceptionHandler mDefaultHandler;
private ICrashHandler mICrashHandler=new ICrashHandler();
private static class ICrashHandler implements UncaughtExceptionHandler
{
private final String EX_LOG_PATH=Environment.getExternalStorageDirectory().getPath()+"/.boyaa/.push/.log/exlog_%s.txt";
@Override
public void uncaughtException(Thread thread, Throwable ex)
{
boolean isHandle=handle(thread,ex);
if(!isHandle&&null!=ICrashMgr.getInstance().mDefaultHandler)
{
ICrashMgr.getInstance().mDefaultHandler.uncaughtException(thread, ex);
}
else
{
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
android.os.Process.killProcess(android.os.Process.myPid());
}
}
/**
* 保存Log文件,需要包括时间,地点(哪台手机),事件
* @param thread
* @param ex
* @return
*/
private boolean handle(Thread thread, final Throwable ex)
{
if(null==ex)
{
return false;
}
StringBuilder sb=new StringBuilder();
sb.append("time:").append(getFormatTime(System.currentTimeMillis(),"yyyy-MM-dd HH:mm:ss")).append("\r\n");//时间
sb.append("phone:").append(getMobileInfo()).append("\r\n");//地点
sb.append("event:").append(getCrashInfo(ex)).append("\r\n").append("\r\n");//事件
write(sb.toString());
return true;
}
/**
* 获取系统时间
* @param time
* @param pattern
* @return
*/
@SuppressLint("SimpleDateFormat")
public String getFormatTime(long time,String pattern)
{
java.text.SimpleDateFormat format = new java.text.SimpleDateFormat(pattern);
java.util.Date date = new java.util.Date(time);
return format.format(date);
}
/**
* 获取手机的硬件信息
* @return
*/
private String getMobileInfo()
{
StringBuffer sb = new StringBuffer();
//通过反射获取系统的硬件信息
try {
Field[] fields = Build.class.getDeclaredFields();
for(Field field: fields)
{
//暴力反射 ,获取私有的信息
field.setAccessible(true);
String name = field.getName();
String value = field.get(null).toString();
sb.append(name+"="+value);
sb.append("&");
}
} catch (Exception e) {
e.printStackTrace();
}
return sb.toString();
}
/**
* 获取错误的信息
* @param arg1
* @return
*/
private String getCrashInfo(Throwable arg1)
{
Writer writer = new StringWriter();
PrintWriter pw = new PrintWriter(writer);
arg1.printStackTrace(pw);
pw.close();
String error= writer.toString();
return error;
}
public boolean write(String log)
{
byte[] data=log.toString().getBytes();
String fileName=String.format(EX_LOG_PATH, getFormatTime(System.currentTimeMillis(),"yyyy-MM-dd"));
return appendFile(fileName,data, 0, data.length);
}
private boolean appendFile(String filename,byte[]data,int datapos,int datalength)
{
RandomAccessFile rf=null;
try {
createFile(filename);
rf= new RandomAccessFile(filename, "rw");
rf.seek(rf.length());
rf.write(data, datapos, datalength);
} catch (Exception e) {
e.printStackTrace();
}finally{
if(rf!=null)
{
try {
rf.close();
} catch (IOException e) {
e.printStackTrace();
}
rf=null;
}
}
return true;
}
private boolean createFile(String filePath)
{
try
{
File file = new File(filePath);
if (!file.exists())
{
if (!file.getParentFile().exists())
{
file.getParentFile().mkdirs();
}
return file.createNewFile();
}
} catch (IOException e)
{
e.printStackTrace();
}
return true;
}
}
}
邮箱:zz7zz7zz@163.com
微博:http://weibo.com/u/3209971935