CrashHandler全局捕获异常,保存本地

原创 2016年08月30日 17:06:38
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.Environment;
import android.os.Looper;
import android.os.Process;
import android.util.Log;
import android.widget.Toast;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.StringWriter;
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.Iterator;
import java.util.Map;
import java.util.Map.Entry;

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 CrashHandler() {
    }

    public static CrashHandler getInstance() {
        return mInstance;
    }

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

    public void uncaughtException(Thread paramThread, Throwable paramThrowable) {
        if(!this.handleException(paramThrowable) && this.mDefaultHandler != null) {
            this.mDefaultHandler.uncaughtException(paramThread, paramThrowable);
        } else {
            try {
                Thread.sleep(1000L);
            } catch (InterruptedException var4) {
                var4.printStackTrace();
            }

            Process.killProcess(Process.myPid());
            System.exit(1);
        }

    }

    public boolean handleException(Throwable paramThrowable) {
        if(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(paramThrowable);
            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(Throwable paramThrowable) {
        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);
        paramThrowable.printStackTrace(mPrintWriter1);

        for(Throwable mThrowable1 = 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();
                return mFileName;
            } catch (FileNotFoundException var11) {
                var11.printStackTrace();
            } catch (IOException var12) {
                var12.printStackTrace();
            }
        }

        return null;
    }
}

需要在application中初始化操作

CrashHandler handler = CrashHandler.getInstance();
handler.init(this);

如果有崩溃错误,可在SD卡CrashInfos目录下查看错误日志

版权声明:本文为博主原创文章,未经博主允许不得转载。

Android全局异常捕获CrashHandler

  • 2016年01月28日 17:01
  • 2.56MB
  • 下载

自定义CrashHandler捕获全局未处理异常

问题:          在我们实际开发中,很多时候有些程序的异常并没有完全进行捕捉处理,如果程序执行到报错的代码时,程序就会强行停止,force close,并且界面对用户来说是不友好的。因此,我们...

Android 全局异常捕获之CrashHandler

一个App上线或者投入到生产环境的时候崩溃了,还不知道是什么原因,这肯定是开发者的痛...所以肯定要加入全局异常捕获,如果项目较大的话,可以考虑加入第三方诸如友盟的崩溃统计插件,以达到异常捕获的效果!...

Android 全局异常捕获之CrashHandler

一个App上线或者投入到生产环境的时候崩溃了,还不知道是什么原因,这肯定是开发者的痛...所以肯定要加入全局异常捕获,如果项目较大的话,可以考虑加入第三方诸如友盟的崩溃统计插件,以达到异常捕获的效果!...

Android全局异常捕获CrashHandler

在Android开发中在所难免的会出现程序crash,俗称崩溃。用户的随意性访问出现测试时未知的Bug导致我们的程序crash,此时我们是无法直接获取的错误log的,也就无法修复Bug。这就会极大的影...

Android 全局异常捕获之CrashHandler,用于开发者收集获取异常信息

一个App上线或者投入到生产环境的时候崩溃了,还不知道是什么原因,这肯定是开发者的痛…所以肯定要加入全局异常捕获,如果项目较大的话,可以考虑加入第三方诸如友盟的崩溃统计插件,以达到异常捕获的效果! ...

Android CrashHandler 自定义崩溃异常捕获

当APP 异常奔溃时,使用Toast提示,并关闭APP,收集错误信息保存并上报 需求:由于android机型的碎片化,我们在开发时无法对所以机型进行测试,因此在可能的崩溃发生时,我们应当做一些事情来...

自定义异常捕获-CrashHandler

说来惭愧,新加入了一家创业公司,加班如同家常便饭,很久没有写博客了,这期间也遇到了不少问题,学习到了挺多东西,现在有点时间了,慢慢的来梳理一下自己遇到的问题吧程序崩溃,几乎是每个程序员都能遇到的问题,...

安卓中捕获未捕获的异常信息CrashHandler

在Android开发中在所难免的会出现程序crash,俗称崩溃。用户的随意性访问出现测试时未知的Bug导致我们的程序crash,此时我们是无法直接获取的错误log的,也就无法修复Bug。这就会极大的影...
  • Me_Dong
  • Me_Dong
  • 2016年12月19日 15:07
  • 339
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:CrashHandler全局捕获异常,保存本地
举报原因:
原因补充:

(最多只允许输入30个字)