使用CrashHandler来捕获Crash异常

对于android 中未捕获到的异常可以通过UnCaughtExceptionHandler
来进行捕获

/**
     * Implemented by objects that want to handle cases where a thread is being
     * terminated by an uncaught exception. Upon such termination, the handler
     * is notified of the terminating thread and causal exception. If there is
     * no explicit handler set then the thread's group is the default handler.
     */
    public static interface UncaughtExceptionHandler {
        /**
         * The thread is being terminated by an uncaught exception. Further
         * exceptions thrown in this method are prevent the remainder of the
         * method from executing, but are otherwise ignored.
         *
         * @param thread the thread that has an uncaught exception
         * @param ex the exception that was thrown
         */
        void uncaughtException(Thread thread, Throwable ex);
    }

他是Thread中的一个内部静态接口,主要通过uncaughtException方法进行处理异常
很显然对这个接口他会抛出get,set方法

  /**
     * Sets the default uncaught exception handler. This handler is invoked in
     * case any Thread dies due to an unhandled exception.
     *
     * @param handler
     *            The handler to set or null.
     */
    public static void setDefaultUncaughtExceptionHandler(UncaughtExceptionHandler handler) {
        Thread.defaultUncaughtHandler = handler;
    }
 /**
     * Returns the default exception handler that's executed when uncaught
     * exception terminates a thread.
     *
     * @return an {@link UncaughtExceptionHandler} or <code>null</code> if
     *         none exists.
     */
    public static UncaughtExceptionHandler getDefaultUncaughtExceptionHandler() {
        return defaultUncaughtHandler;
    }

所以我们由此可以自定义一个CrashHandler来实现这个UncaughtExceptionHandler来处理未捕获到的异常



import android.content.Context;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.os.Build;
import android.os.Environment;
import android.widget.Toast;

import com.orhanobut.logger.Logger;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
import java.lang.Thread.UncaughtExceptionHandler;
import java.text.SimpleDateFormat;
import java.util.Date;

/**
 * author:sparkhuu
 * email:sparkhuu@gmail.com
 */
public class CrashHandler implements UncaughtExceptionHandler {
    private static final String TAG = "CrashHandler";

    private static final boolean DEBUG = true;

    private static final String PATH = Environment.getExternalStorageDirectory().getPath() + "/CrashText/log/";

    private static final String FILE_NAME = "crash";

    private static final String FILE_NAME_SUFFIX = ".trace";

    private static CrashHandler sInstance = new CrashHandler();

    private UncaughtExceptionHandler mDefaultCrashHandler;

    private Context mContext;

    private CrashHandler(){}

    public static CrashHandler getsInstance(){
        return sInstance;
    }

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

    /**
     * 当程序中有未捕获的异常,系统会自动调用此方法
     * @param thread 出现未捕获异常的线程
     * @param ex 未捕获的异常
     */
    @Override
    public void uncaughtException(Thread thread, Throwable ex) {
        try {
            //导出异常信息导SD卡
            dumpExceptionToSDCard(ex);
            //上传异常信息导服务器
            uploadExceptionToServer();
        } catch (Exception e) {
            e.printStackTrace();
        }
        ex.printStackTrace();
        if (null != mDefaultCrashHandler){
            mDefaultCrashHandler.uncaughtException(thread, ex);
        } else {
            Toast.makeText(mContext, ex.getMessage(), Toast.LENGTH_SHORT).show();
        }
    }

    private void uploadExceptionToServer(){



    }

    private void dumpExceptionToSDCard(Throwable ex) throws IOException {
        if (!Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)){
            if (DEBUG){
                Logger.i(TAG + "sdCard unmounted, skip dump exception");
                return;
            }
        }
        File dir = new File(PATH);
        if (!dir.exists()){
            dir.mkdirs();
        }
        long current = System.currentTimeMillis();
        String time = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date(current));
        File file = new File(PATH + FILE_NAME + time + FILE_NAME_SUFFIX);
        try {
            PrintWriter pw = new PrintWriter(new BufferedWriter(new FileWriter(file)));
            pw.println();
            dumpPhoneInfo(pw);
            ex.printStackTrace();
            pw.close();
        }catch (Exception e) {
            Logger.e(TAG + "dump crash info failed");
        }
    }

    private void dumpPhoneInfo(PrintWriter pw) throws PackageManager.NameNotFoundException {
        PackageManager pm = mContext.getPackageManager();
        PackageInfo pi = pm.getPackageInfo(mContext.getPackageName(), PackageManager.GET_ACTIVITIES);
        pw.print("App version:");
        pw.print(pi.versionName);
        pw.print("-");
        pw.println(pi.versionCode);

        //Android版本号
        pw.print("OS version:");
        pw.print(Build.VERSION.RELEASE);
        pw.print("-");
        pw.println(Build.VERSION.SDK_INT);

        // 手机制造商
        pw.print("Vendor:");
        pw.println(Build.MANUFACTURER);

        // 手机型号
        pw.print("Model:");
        pw.println(Build.MODEL);

        //cpu架构
        pw.print("CPU ABI:");
        pw.println(Build.CPU_ABI);
    }

}

最后在Application中进行初始化

        CrashHandler.getsInstance().init(this);

也可以通过tencent的bugly集成来满足开发需求地址为
bugly地址

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
android.os.strictmode.DiskReadViolation at android.os.StrictMode$AndroidBlockGuardPolicy.onReadFromDisk(StrictMode.java:1596) at libcore.io.BlockGuardOs.open(BlockGuardOs.java:249) at libcore.io.ForwardingOs.open(ForwardingOs.java:166) at android.app.ActivityThread$AndroidOs.open(ActivityThread.java:7844) at libcore.io.MemoryMappedFile.mmapRO(MemoryMappedFile.java:54) at libcore.timezone.ZoneInfoDb.loadData(ZoneInfoDb.java:185) at libcore.timezone.ZoneInfoDb.loadTzDataWithFallback(ZoneInfoDb.java:119) at libcore.timezone.ZoneInfoDb.<clinit>(ZoneInfoDb.java:46) at java.util.TimeZone.getTimeZone(TimeZone.java:579) at java.util.TimeZone.getDefaultRef(TimeZone.java:724) at java.util.TimeZone.getDefault(TimeZone.java:700) at java.text.SimpleDateFormat.initializeCalendar(SimpleDateFormat.java:743) at java.text.SimpleDateFormat.<init>(SimpleDateFormat.java:687) at java.text.SimpleDateFormat.<init>(SimpleDateFormat.java:666) at com.hryt.remoter.uimce.app.CrashHandler.<init>(CrashHandler.java:53) at com.hryt.remoter.uimce.app.CrashHandler.<clinit>(CrashHandler.java:49) at com.hryt.remoter.uimce.app.CrashHandler.getInstance(CrashHandler.java:65) at com.hryt.remoter.uimce.app.RemoterApplication.onCreate(RemoterApplication.java:32) at android.app.Instrumentation.callApplicationOnCreate(Instrumentation.java:1192) at android.app.ActivityThread.handleBindApplication(ActivityThread.java:7013) at android.app.ActivityThread.access$1300(ActivityThread.java:238) at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1921) at android.os.Handler.dispatchMessage(Handler.java:106) at android.os.Looper.loop(Looper.java:223) at android.app.ActivityThread.main(ActivityThread.java:7958) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:603) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:947)
最新发布
06-08

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值