UncaughtExceptionHandler捕获异常

public class CrashHandler implements UncaughtExceptionHandler {
    private static final String TAG = "NorrisInfo";
    private UncaughtExceptionHandler mDefaultHandler;
    private static CrashHandler mInstance = new CrashHandler();
    private Context mContext;
    private Map<String, String> mLogInfo = new HashMap();
    private SimpleDateFormat mSimpleDateFormat = new SimpleDateFormat("yyyyMMdd_HH-mm-ss");
    private Thread paramThread;
    private Throwable paramThrowable;
    private CrashHandler.CrashHandlerCallback crashHandlerCallback;

    private CrashHandler() {
    }

    public static CrashHandler getInstance() {
        return mInstance;
    }

    public void init(Context paramContext, CrashHandler.CrashHandlerCallback crashHandlerCallback) {
        this.crashHandlerCallback = crashHandlerCallback;
        this.mContext = paramContext;
        this.mDefaultHandler = Thread.getDefaultUncaughtExceptionHandler();
        Thread.setDefaultUncaughtExceptionHandler(this);
    }

    public void uncaughtException(Thread paramThread, Throwable paramThrowable) {
        this.paramThread = paramThread;
        this.paramThrowable = paramThrowable;
        this.handleException();
    }

    public boolean handleException() {
        if(this.paramThrowable == null) {
            return false;
        } else {
            (new Thread() {
                public void run() {
                    Looper.prepare();
                    Toast.makeText(CrashHandler.this.mContext, "很抱歉,程序出现异常,即将退出", 0).show();
                    Looper.loop();
                }
            }).start();
            this.getDeviceInfo(this.mContext);
            this.saveCrashLogToFile();
            return true;
        }
    }

    public void getDeviceInfo(Context paramContext) {
        try {
            PackageManager mFields = paramContext.getPackageManager();
            PackageInfo field = mFields.getPackageInfo(paramContext.getPackageName(), 1);
            if(field != null) {
                String versionName = field.versionName == null?"null":field.versionName;
                String versionCode = String.valueOf(field.versionCode);
                this.mLogInfo.put("versionName", versionName);
                this.mLogInfo.put("versionCode", versionCode);
            }
        } catch (NameNotFoundException var10) {
            var10.printStackTrace();
        }

        Field[] var11 = Build.class.getDeclaredFields();
        Field[] var6 = var11;
        int var14 = var11.length;

        for(int var13 = 0; var13 < var14; ++var13) {
            Field var12 = var6[var13];

            try {
                var12.setAccessible(true);
                this.mLogInfo.put(var12.getName(), var12.get("").toString());
                Log.d("NorrisInfo", var12.getName() + ":" + var12.get(""));
            } catch (IllegalArgumentException var8) {
                var8.printStackTrace();
            } catch (IllegalAccessException var9) {
                var9.printStackTrace();
            }
        }

    }

    private String saveCrashLogToFile() {
        UsualTools.showPrintMsg("saveCrashLogToFile");
        StringBuffer mStringBuffer = new StringBuffer();
        Iterator mPrintWriter = this.mLogInfo.entrySet().iterator();

        String mResult;
        while(mPrintWriter.hasNext()) {
            Entry mWriter = (Entry)mPrintWriter.next();
            String mThrowable = (String)mWriter.getKey();
            mResult = (String)mWriter.getValue();
            mStringBuffer.append(mThrowable + "=" + mResult + "\r\n");
        }

        StringWriter mWriter1 = new StringWriter();
        PrintWriter mPrintWriter1 = new PrintWriter(mWriter1);
        this.paramThrowable.printStackTrace(mPrintWriter1);
        this.paramThrowable.printStackTrace();

        for(Throwable mThrowable1 = this.paramThrowable.getCause(); mThrowable1 != null; mThrowable1 = mThrowable1.getCause()) {
            mThrowable1.printStackTrace(mPrintWriter1);
            mPrintWriter1.append("\r\n");
        }

        mPrintWriter1.close();
        mResult = mWriter1.toString();
        mStringBuffer.append(mResult);
        String mTime = this.mSimpleDateFormat.format(new Date());
        String mFileName = "CrashLog-" + mTime + ".log";
        if(Environment.getExternalStorageState().equals("mounted")) {
            try {
                File e = new File(Environment.getExternalStorageDirectory() + "/CrashInfos");
                Log.v("NorrisInfo", e.toString());
                if(!e.exists()) {
                    e.mkdir();
                }

                FileOutputStream mFileOutputStream = new FileOutputStream(e + "/" + mFileName);
                mFileOutputStream.write(mStringBuffer.toString().getBytes());
                mFileOutputStream.close();
                this.crashHandlerCallback.onCrashHandle(e, e + "/" + mFileName, mStringBuffer.toString());
                return mFileName;
            } catch (FileNotFoundException var10) {
                var10.printStackTrace();
            } catch (IOException var11) {
                var11.printStackTrace();
            }
        }

        return null;
    }

    public void letDefaultHandlerDeal() {
        this.mDefaultHandler.uncaughtException(this.paramThread, this.paramThrowable);
    }

    public interface CrashHandlerCallback {
        void onCrashHandle(File var1, String var2, String var3);
    }
}

捕获异常以后直接在Application或者Activity的onCreate方法中加入以下两句调用即可

CrashHandler crashHandler = CrashHandler.getInstance();  
crashHandler.init(getApplicationContext());

现在安装 Android 系统的手机版本和设备千差万别,在模拟器上运行良好的程序安装到某款手机上说不定就出现崩溃的现象,开发者个人不可能购买所有设备逐个调试,所以在程序发布出去之后,如果出现了崩溃现象,开发者应该及时获取在该设备上导致崩溃的信息,这对于下一个版本的bug修复帮助极大,所以今天就来介绍一下如何在程序崩溃的情况下收集相关的设备参数信息和具体的异常信息,并发送这些信息到服务器供开发者分析和调试程序。

android.app.Application  和j   ava.lang.Thread.UncaughtExceptionHandler。

Application:用来管理应用程序的全局状态。在应用程序启动时Application会首先创建,然后才会根据情况(Intent)来启动相应的Activity和Service。

Thread.UncaughtExceptionHandler:线程未捕获异常处理器,用来处理未捕获异常。如果程序出现了未捕获异常,默认会弹出系统中强制关闭对话框。我们需要实现此接口,并注册为程序中默认未捕获异常处理。这样当未捕获异常发生时,就可以做一些个性化的异常处理操作。


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值