【Android技巧】--防崩溃处理

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/shankezh/article/details/79332004
简单介绍:
    Android开发过程中,因为各种原因导致app崩溃的现象层出不穷,异常奔溃带来的用户体验及其差劲,尤其当一个小小的功能页面的问题导致app整体奔溃带来的操作感受极差,防止app奔溃,虽然不能从根本解决用户体验的基本问题,但可以在此基础上处理,并带来更好地错误交互处理方法。
    程序中,可以捕捉到的异常,通常使用try...catch..finally来解决,但还存在一些我们没有捕捉到的异常,例如,使用控件不绑定,变量未初始化等,而捕捉这些由于疏忽而产生的异常则使用 UncaughtExceptionHandler对象来实现。
    常见的异常奔溃带来的处理步骤:
    1)将错误异常等记录到本地日志中
    2)弹出弹窗,提醒用户出现bug,请用户配合上传错误日志
    3)提醒用户出现bug的功能暂时不要使用,然后弹到主页面。

UncaughtExceptionHandler的封装(网上已经有人封装好了,直接参考写一下):


/**
* Created by Zhu Hao on 2018/2/7.
*/

/**
* 全局捕获异常信息
* 发生Uncaught异常时,由该类来接管程序
*/
public class CrashHandler implements UncaughtExceptionHandler {

private static final String TAG = "CrashHandler" ;

@SuppressLint ( "StaticFieldLeak" )
private static CrashHandler instance ;
private Thread.UncaughtExceptionHandler mDefaultUEHandler ;
private Context mContext ;


//格式化日期
@SuppressLint ( "SimpleDateFormat" )
private DateFormat dateFormat = new SimpleDateFormat( "yyyy-MM-dd" );

private CrashHandler(){
//获取系统默认UncaughtException处理器
mDefaultUEHandler = Thread. getDefaultUncaughtExceptionHandler ();
}

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



public void init(Context context){
mContext = context;
//设置该CrashHandler为程序的默认处理器
Thread. setDefaultUncaughtExceptionHandler ( this );

}

/**
* 当UncaughExcept发生时会转入该函数来处理
* @param thread
* @param throwable
*/
@Override
public void uncaughtException(Thread thread, Throwable throwable) {
Log. i ( TAG , "uncaughtException: 先捕捉到" );

if (AppParams. DEBUG_EX ){
//调试的时候,记得将DEBUG_EX置成True,
Log. i ( TAG , "uncaughtException: 被系统机制开始处理,app开始崩溃" );
//交由系统默认的错误处理器来处理,也就是"崩溃报错"
mDefaultUEHandler .uncaughtException(thread,throwable);

}
if (handleException(throwable)){
Log. i ( TAG , "uncaughtException: 运行到这里" );
// showDialog(mContext);
//表示被自己写的handlerException处理了,进行收尾操作
// SystemClock.sleep(3000);
Log. i ( TAG , "uncaughtException: CrashHandler处理了" );
} else {
//自己的CrashHandler没有捕捉到异常,交由系统机制进行崩溃处理
mDefaultUEHandler .uncaughtException(thread,throwable);
}

Log. i ( TAG , "uncaughtException: 后捕捉到" );
}

/**
* 自定义错误处理,收集错误信息,发送错误报告等操作
* @param ex
* @return true:如果处理了该错误信息返回true,否则返回false
*/
private boolean handleException( final Throwable ex){
if (ex == null ){
return false ;
}
try {
Log. i ( TAG , "handleException: 发现了个错误,处理中...." );
new Thread(){
@Override
public void run() {
Looper. prepare ();
Toast. makeText ( mContext , "发现个错误" , Toast. LENGTH_SHORT ).show();
Log. i ( TAG , "run: " + ex .toString());

showDialog( mContext );
Looper. loop ();
// showDialog(mContext);
}
}.start();
Log. i ( TAG , "handleException: CrashHandler处理完成" );
} catch (Exception e){
e.printStackTrace();
}
return true ;
}

private void showDialog(Context context){
AlertDialog.Builder builder = new AlertDialog.Builder(context);
builder.setMessage(context.getResources().getString(R.string. app_crashHandler_dialog_summary ));
builder.setTitle(context.getResources().getString(R.string. app_crashHandler_dialog_title ));
builder.setPositiveButton(context.getResources().getString(R.string. app_crashHandler_dialog_upload )
, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
Log. i ( TAG , "onClick: 上传错误日志" );
dialog.dismiss();

}
});
builder.setNegativeButton(context.getResources().getString(R.string.app_crashHandler_dialog_reIndex )
, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
Index. getInstance ().switchFragment(AppParams. FragMenuList );
dialog.dismiss();
}
});
Dialog dialog=builder.create();
dialog.getWindow().setType(WindowManager.LayoutParams. TYPE_SYSTEM_ALERT );
dialog.show();

}
}

其中, AppParams. DEBUG_EX  是封装的全局参数,调试时置成True,报错容易看到,不调试置成false,防止报错,生成错误日志。
Index. getInstance ().switchFragment(AppParams. FragMenuList 是封装的Fragment的切换方法。

使用方法:
在Application中初始化即可:

/**
* Created by Jason Zhu on 2017-08-21.
*/

public class AIO extends Application {
private static AIO instance ;
//用list保存每个Activity
private List<Activity> mActivityList = new LinkedList<Activity>();
private List<Service> mServiceList = new LinkedList<Service>();

public static AIO getInstance(){
if ( null == instance ){
instance = new AIO();
}
return instance ;
}

@Override
public void onCreate() {
super .onCreate();
instance = this ;

//这里使用即可
CrashHandler. getInstance ().init( this );
}



public void AddActivityList(Activity activity){
mActivityList .add(activity);
}

public void AddServiceList(Service service ){
mServiceList .add(service);
}

public void Exit(){

try {
for (Activity activity : mActivityList ){
if ( null != activity){
Log. i ( "Application" , "Exit: " + activity.getLocalClassName());
activity.finish();
}
}

for (Service service : mServiceList ){
if ( null != service){
service.stopSelf();
}
}
} catch (Exception e){
e.printStackTrace();
} finally {
Handler mHandler = new Handler();
mHandler.postDelayed( new Runnable() {
@Override
public void run() {
System. exit ( 0 );
}
}, 200 );
//
}
}
}

参考来源:

猜你喜欢

转载自blog.csdn.net/shankezh/article/details/79332004
今日推荐