一、示例 当捕获到崩溃后,会弹出以下的弹窗出来。
一、创建捕获类
/**
* 应用异常捕获类
* 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>
复制代码