全局错误捕获,自定义处理

Android应用异常捕获

一、示例 当捕获到崩溃后,会弹出以下的弹窗出来。

一、创建捕获类

/**
 * 应用异常捕获类
 * Created by shenhuniurou
 * on 2017/1/3.
 */

public class AppUncaughtExceptionHandler implements UncaughtExceptionHandler {

    //程序的Context对象
    private Context applicationContext;

    private volatile boolean crashing;

    private int waitingTime = 4000;

    /**
     * 日期格式器
     */
    private DateFormat mFormatter = new SimpleDateFormat("yyyy-MM-dd-HH-mm-ss");

    /**
     * 系统默认的UncaughtException处理类
     */
    private UncaughtExceptionHandler mDefaultHandler;

    /**
     * 单例
     */
    private static AppUncaughtExceptionHandler sAppUncaughtExceptionHandler;

    public static synchronized AppUncaughtExceptionHandler getInstance() {
        if (sAppUncaughtExceptionHandler == null) {
            synchronized (AppUncaughtExceptionHandler.class) {
                if (sAppUncaughtExceptionHandler == null) {
                    sAppUncaughtExceptionHandler = new AppUncaughtExceptionHandler();
                }
            }
        }
        return sAppUncaughtExceptionHandler;
    }

    /**
     * 初始化
     *
     * @param context
     */
    public void init(Context context) {
        applicationContext = context.getApplicationContext();
        crashing = false;
        //获取系统默认的UncaughtException处理器
        mDefaultHandler = Thread.getDefaultUncaughtExceptionHandler();
        //设置该CrashHandler为程序的默认处理器
        Thread.setDefaultUncaughtExceptionHandler(this);
    }

    @Override
    public void uncaughtException(Thread thread, Throwable ex) {
        if (crashing) {
            return;
        }
        crashing = true;

        // 打印异常信息
        ex.printStackTrace();
        // 我们没有处理异常 并且默认异常处理不为空 则交给系统处理
        if (!handlelException(ex) && mDefaultHandler != null) {
            // 系统处理
            mDefaultHandler.uncaughtException(thread, ex);
        }
        try {
            Thread.sleep(waitingTime);
        } catch (Exception e) {
        }
        mDefaultHandler.uncaughtException(thread, ex);
//		byebye();
    }

    private void byebye() {
        android.os.Process.killProcess(android.os.Process.myPid());
        System.exit(0);
    }

    private boolean handlelException(Throwable ex) {
        if (ex == null) {
            return false;
        }
        try {
            // 提示对话框
            ShowToast();
        } catch (Exception e) {
            return false;
        }
        return true;
    }

    private void ShowToast() {
        new Thread() {
            @Override
            public void run() {
                Looper.prepare();
                //在此处处理出现异常的情况
                View view = View.inflate(applicationContext, R.layout.dialog_exception, null);
                MyToast mGToast = MyToast.makeText(applicationContext, view, waitingTime);
                mGToast.show();
                Looper.loop();
            }
        }.start();
    }

    private void restart() {
        Intent intent = applicationContext.getPackageManager().getLaunchIntentForPackage(applicationContext.getPackageName());
        intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
        applicationContext.startActivity(intent);
    }

}
复制代码

二、MyToast类

public class MyToast {
    private static final String TAG = "GenericToast";

    private static final int TOAST_TEXTSIZE = 20;

    /**
     * {@link Toast#LENGTH_SHORT} default time is 3500ms
     */
    private static final int LENGTH_SHORT_TIME = 1000;

    private static Context mContext = null;

    private static Toast mToast = null;
    private static TextView mTextView = null;
    private static int mDuration = 0;
    private static View mView = null;

    private Handler mHandler = new Handler();

    private MyToast(Context context) {
        mContext = context;
    }

    public static MyToast makeText(Context context, View view, int duration) {
        MyToast instance = new MyToast(context);
        mContext = context;
        mDuration = duration;
        mView = view;
        return instance;
    }

    private static void getToast(Context context, View view) {
        mToast = Toast.makeText(context, null, Toast.LENGTH_LONG);
        mToast.setGravity(Gravity.CENTER, 0, 0);
        mToast.setView(view);
    }

    /**
     * @return Toast display duration.
     */
    public int getDuration() {
        return mDuration;
    }

    public void show() {
        mHandler.post(showRunnable);
    }

    public void hide() {
        mDuration = 0;
        if (mToast != null) {
            mToast.cancel();
        }
    }

    public void setView(View view) {
        mView = view;
    }

    private Runnable showRunnable = new Runnable() {
        @Override
        public void run() {
            if (mToast != null) {
//                mTextView.setText(mText);
            } else {
                getToast(mContext, mView);
            }
            if (mDuration != 0) {
                mToast.show();
            } else {
                hide();
                return;
            }

            if (mDuration >= LENGTH_SHORT_TIME) {
                mHandler.postDelayed(showRunnable, LENGTH_SHORT_TIME);
                modifyToastMessage(mDuration / 1000);
                mDuration -= LENGTH_SHORT_TIME;
            } else {
                mHandler.postDelayed(showRunnable, mDuration);
                mDuration = 0;
                modifyToastMessage(1);
            }
        }
    };

    public void modifyToastMessage(int time) {
        if (mToast == null || mToast.getView() == null) {
            return;
        }
        View view = mToast.getView();
        TextView tv_message = (TextView) view.findViewById(R.id.dialog_exception_tv_message);
        tv_message.setText("抱歉,发生了未知错误," + time + "秒后关闭应用");
    }
}
复制代码

Toast的布局文件

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:background="@drawable/bg_exception_dialog"
    android:orientation="vertical"
    android:paddingBottom="30dp"
    android:paddingLeft="10dp"
    android:paddingRight="10dp"
    android:paddingTop="30dp">

    <ImageView
        android:layout_width="50dp"
        android:layout_height="50dp"
        android:layout_gravity="center_horizontal"
        android:src="@drawable/ic_exception" />

    <TextView
        android:id="@+id/dialog_exception_tv_message"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="10dp"
        android:layout_gravity="center_horizontal"
        android:gravity="center_horizontal"
        android:text="抱歉,发生了未知错误,3秒后关闭应用"
        android:textColor="@color/common_white"
        android:textSize="16sp"
        android:textStyle="bold" />
</LinearLayout>
复制代码

转载于:https://juejin.im/post/5b3ac62ee51d4555a9598b26

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值