源码下载“:http://www.eoeandroid.com/thread-587310-1-1.html
当我们的应用在出现bug并强制退出的时候,我们可能不捕捉不了相关的异常,不过,我们可以设置自定义的异常来捕捉全局异常
1.捕捉全局异常的类
-
package com.happy.application;
-
-
import java.io.File;
-
import java.io.FileOutputStream;
-
import java.io.PrintWriter;
-
import java.io.StringWriter;
-
import java.io.Writer;
-
import java.lang.Thread.UncaughtExceptionHandler;
-
import java.lang.reflect.Field;
-
import java.text.SimpleDateFormat;
-
import java.util.Date;
-
import java.util.HashMap;
-
import java.util.Map;
-
-
import android.app.Application;
-
import android.content.Context;
-
import android.content.pm.PackageInfo;
-
import android.content.pm.PackageManager;
-
import android.content.pm.PackageManager.NameNotFoundException;
-
import android.os.Build;
-
import android.os.Looper;
-
import android.widget.Toast;
-
-
import com.happy.common.Constants;
-
import com.happy.logger.LoggerManage;
-
-
public class CrashApplication extends Application {
-
-
@Override
-
public void onCreate() {
-
super.onCreate();
-
CrashHandler catchHandler = new CrashHandler();
-
catchHandler.init(getApplicationContext());
-
}
-
-
/**
-
* UncaughtException处理类,当程序发生Uncaught异常的时候,有该类来接管程序,并记录错误报告.
-
*
-
* 需要在Application中注册,为了要在程序启动器就监控整个程序。
-
*/
-
public class CrashHandler implements UncaughtExceptionHandler {
-
-
private LoggerManage logger;
-
private SimpleDateFormat crashfile = new SimpleDateFormat("yyyy-MM-dd");// 日志文件格式
-
-
// 系统默认的UncaughtException处理类
-
private Thread.UncaughtExceptionHandler mDefaultHandler;
-
// 程序的Context对象
-
private Context mContext;
-
// 用来存储设备信息和异常信息
-
private Map<String, String> infos = new HashMap<String, String>();
-
-
/** 保证只有一个CrashHandler实例 */
-
private CrashHandler() {
-
}
-
-
/**
-
* 初始化
-
*/
-
public void init(Context context) {
-
mContext = context;
-
logger = LoggerManage.getZhangLogger(mContext);
-
// 获取系统默认的UncaughtException处理器
-
mDefaultHandler = Thread.getDefaultUncaughtExceptionHandler();
-
// 设置该CrashHandler为程序的默认处理器
-
Thread.setDefaultUncaughtExceptionHandler(this);
-
}
-
-
/**
-
* 当UncaughtException发生时会转入该函数来处理
-
*/
-
@Override
-
public void uncaughtException(Thread thread, Throwable ex) {
-
if (!handleException(ex) && mDefaultHandler != null) {
-
// 如果用户没有处理则让系统默认的异常处理器来处理
-
mDefaultHandler.uncaughtException(thread, ex);
-
} else {
-
try {
-
Thread.sleep(1000);
-
} catch (InterruptedException e) {
-
logger.e(e.toString());
-
}
-
// 退出程序
-
android.os.Process.killProcess(android.os.Process.myPid());
-
System.exit(1);
-
}
-
}
-
-
/**
-
* 自定义错误处理,收集错误信息 发送错误报告等操作均在此完成.
-
*
-
* @param ex
-
* [url=home.php?mod=space&uid=7300]@return[/url] true:如果处理了该异常信息;否则返回false.
-
*/
-
private boolean handleException(Throwable ex) {
-
if (ex == null) {
-
return false;
-
}
-
// 收集设备参数信息
-
collectDeviceInfo(mContext);
-
// 使用Toast来显示异常信息
-
new Thread() {
-
@Override
-
public void run() {
-
Looper.prepare();
-
Toast.makeText(mContext, "程序出现异常,即将退出", Toast.LENGTH_SHORT)
-
.show();
-
Looper.loop();
-
}
-
}.start();
-
// 保存日志文件
-
saveCatchInfoFile(ex);
-
return true;
-
}
-
-
/**
-
* 收集设备参数信息
-
*
-
* @param mContext
-
*/
-
private void collectDeviceInfo(Context ctx) {
-
// 获取当前程序的版本号. 版本的id
-
try {
-
PackageManager pm = ctx.getPackageManager();
-
PackageInfo pi = pm.getPackageInfo(ctx.getPackageName(),
-
PackageManager.GET_ACTIVITIES);
-
if (pi != null) {
-
String versionName = pi.versionName == null ? "null"
-
: pi.versionName;
-
String versionCode = pi.versionCode + "";
-
infos.put("versionName", versionName);
-
infos.put("versionCode", versionCode);
-
}
-
} catch (NameNotFoundException e) {
-
logger.e(e.toString());
-
}
-
// 获取手机的硬件信息
-
// 通过反射获取系统的硬件信息
-
Field[] fields = Build.class.getDeclaredFields();
-
for (Field field : fields) {
-
try {
-
field.setAccessible(true);
-
infos.put(field.getName(), field.get(null).toString());
-
} catch (Exception e) {
-
logger.e(e.toString());
-
}
-
}
-
}
-
-
/**
-
* 保存日志文件
-
*
-
* @param ex
-
*/
-
private void saveCatchInfoFile(Throwable ex) {
-
-
StringBuffer sb = new StringBuffer();
-
for (Map.Entry<String, String> entry : infos.entrySet()) {
-
String key = entry.getKey();
-
String value = entry.getValue();
-
sb.append(key + "=" + value + "\n");
-
}
-
-
Writer writer = new StringWriter();
-
PrintWriter printWriter = new PrintWriter(writer);
-
ex.printStackTrace(printWriter);
-
Throwable cause = ex.getCause();
-
while (cause != null) {
-
cause.printStackTrace(printWriter);
-
cause = cause.getCause();
-
}
-
printWriter.close();
-
String result = writer.toString();
-
sb.append(result);
-
try {
-
// 用于格式化日期,作为日志文件名的一部分
-
String time = crashfile.format(new Date());
-
String fileName = time + ".log";
-
String path = Constants.PATH_CRASH + File.separator;
-
File dir = new File(path);
-
if (!dir.exists()) {
-
dir.mkdirs();
-
}
-
FileOutputStream fos = new FileOutputStream(path + fileName);
-
fos.write(sb.toString().getBytes());
-
fos.close();
-
} catch (Exception e) {
-
logger.e(e.toString());
-
}
-
}
-
}
-
}
<application
android:name="com.happy.application.CrashApplication"
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
3.调用
-
package com.happy.ui;
-
-
import com.happy.logger.LoggerManage;
-
-
import android.os.Bundle;
-
import android.app.Activity;
-
import android.view.Menu;
-
-
public class MainActivity extends Activity {
-
-
private LoggerManage logger;
-
-
@Override
-
protected void onCreate(Bundle savedInstanceState) {
-
super.onCreate(savedInstanceState);
-
setContentView(R.layout.activity_main);
-
init();
-
}
-
-
private void init() {
-
// logger = LoggerManage.getZhangLogger(this);
-
logger.i("测试");
-
}
-
-
// @Override
-
// public boolean onCreateOptionsMenu(Menu menu) {
-
// getMenuInflater().inflate(R.menu.main, menu);
-
// return true;
-
// }
-
-
}