package com.liyu.fakeweather;
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.liyu.fakeweather.utils.FileUtil;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.lang.Thread.UncaughtExceptionHandler;
import java.util.HashMap;
import java.util.Map;
/**
* 应用系统异常退出,处理类
*
*/
public class AppExceptionHandler implements UncaughtExceptionHandler {
private Context mContext;
private static AppExceptionHandler instance;
public static AppExceptionHandler getInstance() {
if (instance == null) {
synchronized (AppExceptionHandler.class) {
if (instance == null) {
instance = new AppExceptionHandler();
}
}
}
return instance;
}
@Override
public void uncaughtException(Thread thread, Throwable ex) {
handleException(ex);
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.exit(0);
}
/**
* 为我们的应用程序设置自定义Crash处理
*/
public void setCrashHanler(Context context) {
mContext = context;
Thread.setDefaultUncaughtExceptionHandler(this);
}
/**
* 显示提示信息,需要在线程中显示Toast
*
* @param context
* @param msg
*/
private void showToast(final Context context, final String msg) {
new Thread(new Runnable() {
@Override
public void run() {
Looper.prepare();
Toast.makeText(context, msg, Toast.LENGTH_LONG).show();
Looper.loop();
}
}).start();
}
/**
* 获取一些简单的信息,软件版本,手机版本,型号等信息存放在HashMap中
*
* @param context
* @return
*/
private HashMap<String, String> obtainSimpleInfo(Context context) {
HashMap<String, String> map = new HashMap<String, String>();
PackageManager mPackageManager = context.getPackageManager();
PackageInfo mPackageInfo = null;
try {
mPackageInfo = mPackageManager.getPackageInfo(
context.getPackageName(), PackageManager.GET_ACTIVITIES);
} catch (NameNotFoundException e) {
e.printStackTrace();
}
map.put("versionName", mPackageInfo.versionName);
map.put("versionCode", "" + mPackageInfo.versionCode);
map.put("MODEL", "" + Build.MODEL);
map.put("SDK_INT", "" + Build.VERSION.SDK_INT);
map.put("PRODUCT", "" + Build.PRODUCT);
return map;
}
/**
* 获取系统未捕捉的错误信息
*
* @param throwable
* @return
*/
private String obtainExceptionInfo(Throwable throwable) {
StringWriter mStringWriter = new StringWriter();
PrintWriter mPrintWriter = new PrintWriter(mStringWriter);
throwable.printStackTrace(mPrintWriter);
mPrintWriter.close();
return mStringWriter.toString();
}
/**
* 处理异常信息
*
* @param ex
*/
protected void handleException(Throwable ex) {
final StringBuffer sb = new StringBuffer();
for (Map.Entry<String, String> entry : obtainSimpleInfo(mContext).entrySet()) {
String key = entry.getKey();
String value = entry.getValue();
sb.append(key).append(" = ").append(value).append("\n");
}
sb.append(obtainExceptionInfo(ex));
FileUtil.writeLogCrashContent(sb.toString());
showToast(mContext, String.format("%s\n%s", "很抱歉,程序遭遇异常,即将退出!", sb.toString()));
}
}