? ? 转载请注明出处:http://blog.csdn.net/zhaokaiqiang1992
? ? 尽管我们的程序在正式上线之前,都会经过严格的測试。从而保证程序的健壮性和良好的用户体验,可是,一个人的測试或者是几个人的測试团队,都不能和上万甚至数十万的用户相比。因此。前期刚上线的程序在用户手里被玩崩了,也是非经常见的事,可是。假设我们不做特殊处理。系统自带的程序崩溃提示真的太吓人了,用户看到之后会不知所措。因此,我们须要一个解决方式。就是在程序即将崩溃的时候。给用户一个更加友好的提示。来告诉他,程序立即要崩溃了。
? ? 就像是以下这样:
? ? ?这样是不是更加友好一点呢?
? ? 以下解说怎样实现。
? ? ?假设要实现这样的功能。我们须要关注的是Thread类里面的一个接口,UncaughtExceptionHandler,另一个设置Thread.setDefaultUncaughtExceptionHandler(),这两个东西究竟是干嘛的呢?
? ??UncaughtExceptionHandler 这个接口是当Thread由于未被捕获的异常而要被终止的时候。会被调用的回调接口。
? ? 而Thread.setDefaultUncaughtExceptionHandler()这种方法,则是设置当线程由于未捕获到异常而突然终止,而且没有为该线程定义其它处理程序时所调用的默认处理程序。
? ? 因此,假设我们想自己处理程序要崩溃时的处理逻辑,我们仅仅须要实现UncaughtExceptionHandler接口,并调用Thread.setDefaultUncaughtExceptionHandler()设置就可以。
? ? 以下是演示样例代码
? ? 首先。先给出上面效果图中的Activity的代码
package com.example.exceptiondemo; import android.app.Activity; import android.os.Bundle; import android.view.View; public class MainActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); // 注冊默认的未捕捉异常处理类 Thread.setDefaultUncaughtExceptionHandler(AppException .getAppExceptionHandler()); AppManager.getAppManager().addActivity(this); } public void btn(View view) { // 除零错误,程序会崩溃 int c = 1 / 0; } }
? ? 在这段代码里面,我们有益写了一个会出现异常的操作,除零。因此仅仅要点击button。程序就会崩溃。
? ? 以下,我们要自己实现接口。这里,我继承了Exception类。
package com.example.exceptiondemo; import java.lang.Thread.UncaughtExceptionHandler; import android.app.Activity; import android.app.AlertDialog; import android.content.DialogInterface; import android.content.DialogInterface.OnClickListener; import android.os.Looper; import android.widget.Toast; /** * * @ClassName: com.example.exceptiondemo.AppException * @Description: 应用程序异常类:用于捕获异常 * @author zhaokaiqiang * @date 2014-11-2 下午10:06:49 * */ public class AppException extends Exception implements UncaughtExceptionHandler { private static final long serialVersionUID = -6262909398048670705L; private String message; private Thread.UncaughtExceptionHandler mDefaultHandler; private AppException() { super(); this.mDefaultHandler = Thread.getDefaultUncaughtExceptionHandler(); } public AppException(String message, Exception excp) { super(message, excp); this.mDefaultHandler = Thread.getDefaultUncaughtExceptionHandler(); } public String getMessage() { return message; } public void setMessage(String message) { this.message = message; } /** * 获取APP异常崩溃处理对象 * * @param context * @return */ public static AppException getAppExceptionHandler() { return new AppException(); } @Override public void uncaughtException(Thread thread, Throwable ex) { if (!handleException(ex) && mDefaultHandler != null) { mDefaultHandler.uncaughtException(thread, ex); } } /** * 自己定义异常处理 * * @param ex * @return true:处理了该异常信息;否则返回false */ private boolean handleException(Throwable ex) { if (ex == null) { return false; } final Activity activity = AppManager.getAppManager().currentActivity(); if (activity == null) { return false; } new Thread() { @Override public void run() { Looper.prepare(); Toast.makeText(activity, "程序要崩了", Toast.LENGTH_SHORT).show(); new AlertDialog.Builder(activity).setTitle("提示") .setCancelable(false).setMessage("亲。程序立即崩溃了...") .setNeutralButton("没关系", new OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { AppManager.getAppManager().exitApp(activity); } }).create().show(); Looper.loop(); } }.start(); return true; } }
? ? 实现借口之后。我们须要在uncaughtException()方法里面处理自己的逻辑,我在这里面弹出对话框提示用户程序崩溃,这样。就比較友好一些。在代码里面的AppManager类是一个Activity的管理类。以下是代码
package com.example.exceptiondemo; import java.util.Stack; import android.app.Activity; import android.app.ActivityManager; import android.content.Context; /** * * @ClassName: net.oschina.app.AppManager * @Description: Activity管理类:用于管理Activity和退出程序 * @author zhaokaiqiang * @date 2014-11-2 上午11:27:55 * */ public class AppManager { private static Stack<Activity> activityStack; private static AppManager instance; private AppManager() { } /** * 单一实例 */ public static AppManager getAppManager() { if (instance == null) { instance = new AppManager(); } return instance; } /** * 加入Activity到堆栈 */ public void addActivity(Activity activity) { if (activityStack == null) { activityStack = new Stack<Activity>(); } activityStack.add(activity); } /** * 获取当前Activity(堆栈中最后一个压入的) */ public Activity currentActivity() { Activity activity = activityStack.lastElement(); return activity; } /** * 结束当前Activity(堆栈中最后一个压入的) */ public void finishActivity() { Activity activity = activityStack.lastElement(); finishActivity(activity); } /** * 结束指定的Activity */ public void finishActivity(Activity activity) { if (activity != null) { activityStack.remove(activity); activity.finish(); activity = null; } } /** * 结束指定类名的Activity */ public void finishActivity(Class<?> cls) { for (Activity activity : activityStack) { if (activity.getClass().equals(cls)) { finishActivity(activity); } } } /** * 结束全部Activity */ public void finishAllActivity() { for (int i = 0, size = activityStack.size(); i < size; i++) { if (null != activityStack.get(i)) { activityStack.get(i).finish(); } } activityStack.clear(); } /** * 退出应用程序 */ public void exitApp(Context context) { try { finishAllActivity(); ActivityManager activityMgr = (ActivityManager) context .getSystemService(Context.ACTIVITY_SERVICE); activityMgr.killBackgroundProcesses(context.getPackageName()); System.exit(0); } catch (Exception e) { } } }
? ? Demo下载地址:https://github.com/ZhaoKaiQiang/ExceptionDemo