APP级别处理未捕获异常

时间:2021-06-28 20:47:16

前言:

  项目APP有时候会出现Crash,然后就是弹出系统强制退出的对话框,点击关闭APP。

  有的APP进行了处理,会发现,当程序出现异常的时候,会Toast一个提示“程序出现异常,3秒后将退出程序”。3秒后即关闭程序而不再显示强制关闭的对话框。

  那么它们是如何处理没有try-catch 捕获到的异常进行界面友好提示优化的处理呢。

  这里我们通过一个demo学习一下。

 

----------------------------------------------------------------------------------------------------------------

一、创建一个类 CrashHandler 实现 UncaughtExceptionHandler 接口 , 当程序发生未捕获异常时 由该类进行处理

  

public class CrashHandler implements Thread.UncaughtExceptionHandler{

private Thread.UncaughtExceptionHandler mDefaultHandler;
Context context;

//CrashHandler实例
private static CrashHandler instance;

/** 获取CrashHandler实例 ,单例模式 */
public static CrashHandler getInstance() {
if (instance == null)
instance
= new CrashHandler();
return instance;
}
/**
* 初始化
*/
public void init(Context context) {
this.context = context;
//获取系统默认的UncaughtException处理器
mDefaultHandler = Thread.getDefaultUncaughtExceptionHandler();
//设置该CrashHandler为程序的默认处理器
Thread.setDefaultUncaughtExceptionHandler(this);
}
    
  
  //实现uncaughException方法 @Override
public void uncaughtException(Thread thread, Throwable ex) {
if (!solveException(ex) && mDefaultHandler != null){
//如果用户没有处理则让系统默认的异常处理器处理

mDefaultHandler.uncaughtException(thread, ex);
}
else{
       // 等待2秒钟后关闭程序
try {
Thread.sleep(
2000);
}
catch (InterruptedException e) {
e.printStackTrace();
}

android.os.Process.killProcess(android.os.Process.myPid());
System.exit(
1);
}
}

/*
* 错误处理
*
*/
private boolean solveException(Throwable e){
if (e == null){
return false;
}
new Thread() {
@Override
public void run() {
Looper.prepare();
Toast.makeText(context,
"程序出现异常,2秒后退出",Toast.LENGTH_SHORT).show();
Looper.loop();
}
}.start();
return true;
}

}

 

二、创建一个基础Application的类MApplication

在onCreate()方法中进行初始化

public class MApplication extends Application{

@Override
public void onCreate() {
super.onCreate();
CrashHandler.getInstance().init(getApplicationContext());
}

}

别忘了在AndroidManifest.xml中添加

<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:supportsRtl="true"

android:name=".MApplication"

android:theme="@style/AppTheme">

 

三、模拟一个异常

  给一个没有绑定的TextView赋值  , 空指针的异常 

public class MainActivity extends Activity {

private TextView text;
private TextView aa;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

text
= (TextView) findViewById(R.id.text);
text.setOnClickListener(
new View.OnClickListener() {
@Override
public void onClick(View v) {
text.setText(
"ni hao");
aa.setText(
"nihao ");
}
});

}
}

 

效果图:

APP级别处理未捕获异常

 

因为我们不可能给每一个方法都try-catch。所以总会有没有捕获到的异常出现。

进行对未捕获异常的处理,可以提高一个用户体验。

开发者们 也可以 在这个处理中添加异常分析,将出现的异常设备、原因、时间等信息提交到自己的服务器上方便以后分析。