Android 全局异常捕获 CrashHandler
博客专区 > 秀宇 的博客 > 博客详情
Android 全局异常捕获 CrashHandler
秀宇 发表于1年前
Android 全局异常捕获 CrashHandler
  • 发表于 1年前
  • 阅读 102
  • 收藏 1
  • 点赞 0
  • 评论 0

标题:腾讯云 新注册用户域名抢购1元起>>>   

摘要: 自定义全局异常捕获。 说明一下 : Java的Thread中有一个UncaughtExceptionHandler接口,该接口的作用主要是为了 当 Thread 因未捕获的异常而突然终止时,调用处理程序。
捕获异常 并且 保存到日志文件的类。
package com.and.mvp.base.base;

import android.content.Context;
import android.content.pm.PackageInfo;
import android.os.Build;
import android.os.Environment;
import android.text.TextUtils;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
import java.lang.Thread.UncaughtExceptionHandler;
import java.text.DecimalFormat;
import java.util.Calendar;
import java.util.TimeZone;

public class CarshHandler implements UncaughtExceptionHandler {
    private static Context cxt;
    private UncaughtExceptionHandler mPrevious;
    /**
     * android系统版本
     */
    private static String ANDROID = Build.VERSION.RELEASE;
    /**
     * 机型
     */
    private static String MODEL = Build.MODEL;
    /**
     * 手机牌子
     */
    private static String MANUFACTURER = Build.MANUFACTURER;
    public static String VERSION = "Unknown";
    private static CarshBuilder mBuilder;
    private boolean isAppend;
    private boolean isSimple;

    /**
     * @param isSimple 是否为简单的日志记录模式
     */
    public void setSimple(boolean isSimple) {
        this.isSimple = isSimple;
    }

    /**
     * @param isAppend 是否为日志追加模式
     */
    public CarshHandler setAppend(boolean isAppend) {
        this.isAppend = isAppend;
        return this;
    }

    private CarshHandler() {
        mPrevious = Thread.currentThread().getUncaughtExceptionHandler();
        Thread.currentThread().setUncaughtExceptionHandler(this);
    }

    public static CarshHandler init(Context context, String dirName) {
        cxt = context;
        try {
            PackageInfo info = context.getPackageManager().getPackageInfo(context.getPackageName(), 0);
            VERSION = info.versionName + info.versionCode;
            mBuilder = CarshBuilder.build(context, dirName);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
        return new CarshHandler();
    }

    private static String formatNumber(int value) {
        return new DecimalFormat("00").format(value);
    }

    private static String getCurrentDate() {
        Calendar calendar = Calendar.getInstance(TimeZone.getTimeZone("GMT+08:00"));
        return calendar.get(Calendar.YEAR) + "-" + formatNumber((calendar.get(Calendar.MONTH) + 1)) + "-"
                + formatNumber(calendar.get(Calendar.DAY_OF_MONTH)) + "  "
                + formatNumber(calendar.get(Calendar.HOUR_OF_DAY)) + ":" + formatNumber(calendar.get(Calendar.MINUTE));
    }

    @Override
    public void uncaughtException(Thread thread, Throwable throwable) {
        File f = new File(mBuilder.getCarsh_log());
        if (f.exists()) {
            if (!isAppend)
                f.delete();
        } else {
            try {
                new File(mBuilder.getCarsh_dir()).mkdirs();
                f.createNewFile();
            } catch (Exception e) {
                return;
            }
        }

        PrintWriter p;
        try {
            p = new PrintWriter(new FileWriter(f, true));
        } catch (Exception e) {
            return;
        }
        p.write("\n*************---------Carsh  Log  Head ------------****************\n\n");
        p.write("Happend Time: " + getCurrentDate() + "\n");
        p.write("Android Version: " + ANDROID + "\n");
        p.write("Device Model: " + MODEL + "\n");
        p.write("Device Manufacturer: " + MANUFACTURER + "\n");
        p.write("App Version: v" + VERSION + "\n\n");
        p.write("*************---------Carsh  Log  Head ------------****************\n\n");
        if (!isSimple) {
            throwable.printStackTrace(p);
        } else {
            p.write(throwable.getLocalizedMessage() + "\n");
        }
        p.close();
        try {
            new File(mBuilder.getCarsh_tag()).createNewFile();
        } catch (Exception e) {
            return;
        }

        if (mPrevious != null) {
            mPrevious.uncaughtException(thread, throwable);
        }
    }

    public static class CarshBuilder {
        private String carsh_dir;

        public String getCarsh_dir() {
            return carsh_dir;
        }

        public String getCarsh_log() {
            return getCarsh_dir() + File.separator + "carshRecord.log";
        }

        public String getCarsh_tag() {

            return getCarsh_dir() + File.separator + ".carshed";
        }

        public CarshBuilder(Context context, String dirName) {
            if (!Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState())) {
                this.carsh_dir = context.getCacheDir().getPath() + File.separator + dirName;
            } else
                this.carsh_dir = Environment.getExternalStorageDirectory().getPath() + File.separator + dirName;
        }

        public static CarshBuilder build(Context context, String dirName) {
            return new CarshBuilder(context, dirName);
        }

        @Override
        public String toString() {
            return "CarshBuilder [dir path: " + getCarsh_dir() + "-- log path:" + getCarsh_log() + "-- tag path:"
                    + getCarsh_tag() + "]";
        }
    }

    /**
     * 获取log 日志路径
     */
    public static String getLogFilePath() {
        if (mBuilder == null)
            return "Unknown";
        else
            return mBuilder.getCarsh_log();
    }

    /**
     * 获取 LOG 记录的内容
     */
    public static String getLogContent() {
        if (TextUtils.isEmpty(getLogFilePath()))
            return null;

        File file = new File(getLogFilePath());
        if (file.exists() && file.isFile()) {
            BufferedReader bis = null;
            try {
                bis = new BufferedReader(new FileReader(file));
                String buffer = null;
                StringBuilder sb = new StringBuilder();
                while ((buffer = bis.readLine()) != null) {
                    sb.append(buffer);
                }
                return sb.toString();
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                try {
                    if (bis != null)
                        bis.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return null;
    }
}

 

//在Application里面进行初始化

public class BApplication extends Application implements Thread.UncaughtExceptionHandler {

    @Override
    public void onCreate() {
        super.onCreate();

    //作用为设置当线程由于未捕获到异常而突然终止,并且没有为该线程定义其他处理程序时所调用的默认处理程序。
        Thread.setDefaultUncaughtExceptionHandler(this);
        //setAppend是否为追加模式, setSimple是否是简单的log信息,
        CarshHandler.init(this, "CarshHandler").setAppend(true).setSimple(false);

    }

    @Override
    public void uncaughtException(Thread thread, Throwable ex) {
        //调用这个方法说明程序异常了,在这里可以推出程序 或者 重启应用程序
    ext();
    }

    // 重新启动应用程序
    private void ext() {
        Intent intent = new Intent(getApplicationContext(), StartActivity.class);
        PendingIntent restartIntent = PendingIntent.getActivity(getApplicationContext(), 0, intent,
                Intent.FLAG_ACTIVITY_NEW_TASK);
        AlarmManager mgr = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
        mgr.set(AlarmManager.RTC, System.currentTimeMillis() + 1000, restartIntent); // 1秒钟后重启应用
        // 杀死该应用进程
        android.os.Process.killProcess(android.os.Process.myPid());
    }

}

也可以在Activity 里面得到 日志保存的路径和错误日志内容

"日志路径 : " + CarshHandler.getLogFilePath() + " ---- 日志内容 : " + CarshHandler.getLogContent());

最后别忘了 android:name=".base.BApplication" 

 

 

 

 

共有 人打赏支持
粉丝 3
博文 7
码字总数 7272
×
秀宇
如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!
* 金额(元)
¥1 ¥5 ¥10 ¥20 其他金额
打赏人
留言
* 支付类型
微信扫码支付
打赏金额:
已支付成功
打赏金额: