Android系统的“程序异常退出”,给应用的用户体验造成不良影响。为了捕获应用运行时异常并给出友好提示,便可继承UncaughtExceptionHandler类来处理。通过Thread.setDefaultUncaughtExceptionHandler()方法将异常处理类设置到线程上即可。
写一个例子来理解.
1.新建项目,新建一个MyCatchException类,实现uncaughtExceptionHandler.
//全部错误捕捉器
public class MyCatchException implements UncaughtExceptionHandler {
//本类实例
private static MyCatchException mInstance;
//系统默认的uncatchException
private Thread.UncaughtExceptionHandler mDefaultException;
private Context mContext;
//保证只有一个实例
public MyCatchException() {
}
//单例模式
public static MyCatchException getInstance(){
if(mInstance==null){
mInstance=new MyCatchException();
}
return mInstance;
}
//获取系统默认的异常处理器,并且设置本类为系统默认处理器
public void init(Context ctx){
this.mContext=ctx;
mDefaultException=Thread.getDefaultUncaughtExceptionHandler();
Thread.setDefaultUncaughtExceptionHandler(this);
}
//自定义错误处理器
private boolean handlerException(Throwable ex){
if(ex==null){ //如果已经处理过这个Exception,则让系统处理器进行后续关闭处理
return false;
}
//获取错误原因
final String msg = ex.getLocalizedMessage();
new Thread(){
public void run() {
// Toast 显示需要出现在一个线程的消息队列中
Looper.prepare();
Toast.makeText(mContext, "程序出错啦:" + msg, Toast.LENGTH_LONG).show();
Looper.loop();
};
}.start();
return true;
}
@Override
public void uncaughtException(Thread thread, Throwable ex) {
if (!handlerException(ex) && mDefaultException != null) {
// 如果用户没有处理则让系统默认的异常处理器来处理
mDefaultException.uncaughtException(thread, ex);
}
else{ //否则自己进行处理
try { //Sleep 来让线程停止一会是为了显示Toast信息给用户,然后Kill程序
Thread.sleep(3000);
} catch (InterruptedException e) {
Log.e("info", "Error : ", e);
}
android.os.Process.killProcess(android.os.Process.myPid());
System.exit(10);
}
}
}
2,新建一个MyApplication继承自Application
public class MyApplication extends Application {
@Override
public void onCreate() {
super.onCreate();
MyCatchException mException=MyCatchException.getInstance();
mException.init(getApplicationContext()); //注册
}
}
3,在MainActivity.java中抛出异常
public class MainActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
throw new NullPointerException();
}
}
4,另外,为了让MyApplication起作用,还需要在AndroidManifest.xml中声明
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.mycrashdemo"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="14"
android:targetSdkVersion="21" />
<application
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:name="com.example.mycrashdemo.MyApplication"
android:theme="@style/AppTheme" >
<activity
android:name=".MainActivity"
android:label="@string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
如此,便可以在程序异常崩溃时,做一些处理,提升用户体验