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())); } }