android 手机无响应 ANR 重启和解决思路

android总是会突然ANR,这涉及到很多原因。我们只能尽量减少ANR发生的情况,但是却没法完全解决掉。

《android 手机无响应 ANR 重启和解决思路》 Paste_Image.png

ANR的出现对用户的体验是非常差的,所以这里给出ANR的解决办法。

1.屏蔽ANR提示
2.自动启动APP
3.发送错误信息给服务器

实现过程如下:

实现异常处理接口:

public class MyCrashHandler implements Thread.UncaughtExceptionHandler 

构造起单例模式:

private static MyCrashHandler myCrashHandler ;
private Thread.UncaughtExceptionHandler mDefaultHandler;
private Context context;
 public static synchronized MyCrashHandler getInstance(){
  if(myCrashHandler!=null){
   return myCrashHandler;
  }else {
   myCrashHandler  = new MyCrashHandler();
   return myCrashHandler;
  }
 }
 public void init(Context context){
     mDefaultHandler = Thread.getDefaultUncaughtExceptionHandler();
     this.context = context;
 }

实现ANR重启

 public void uncaughtException( final Thread thread,  final Throwable ex) {

     if (!handleException(ex) && mDefaultHandler != null) {
         //如果用户没有处理则让系统默认的异常处理器来处理  
         mDefaultHandler.uncaughtException(thread, ex);
     } else {
         try {
             Thread.sleep(3000);
         } catch (InterruptedException e) {
             
         }
     
         //     干掉当前的程序 
//         android.os.Process.killProcess(android.os.Process.myPid());
//         //退出程序  
         Intent intent = new Intent( BaseApplication.getInstance().getApplicationContext(), WelcomeActivity.class);
         PendingIntent restartIntent = PendingIntent.getActivity(
                 BaseApplication.getInstance().getApplicationContext(), 0, intent,
                 Intent.FLAG_ACTIVITY_NEW_TASK);
         //退出程序                                          
         AlarmManager mgr = (AlarmManager) BaseApplication.getInstance().getSystemService(Context.ALARM_SERVICE);
         mgr.set(AlarmManager.RTC, System.currentTimeMillis() + 1000,
                 restartIntent); // 1秒钟后重启应用  
         BaseApplication.getInstance().finishActivity();
//         System.exit(1);
   
     }

最后是在重启前,发送错误报告


    private boolean handleException(Throwable ex) {
        if (ex == null) {
            return false;
        }
      ex.printStackTrace();
        //使用Toast来显示异常信息  
        new Thread() {
            @Override
            public void run() {
                Looper.prepare();
                Toast.makeText(context, "很抱歉,程序出现异常,即将重启.", Toast.LENGTH_LONG).show();
                Looper.loop();
            }
        }.start();
        System.out.println("程序挂掉了 ");
        // 1.获取当前程序的版本号. 版本的id
        String versioninfo = getVersionInfo();

        // 2.获取手机的硬件信息.
        String mobileInfo  = getMobileInfo();

        // 3.把错误的堆栈信息 获取出来 
        String errorinfo = getErrorInfo(ex);
        Map<String, String> params = new HashMap<String, String>();
        params.put("SERVICE_TYPE", Local.NET_ERROR);
        params.put("LOGIN_TYPE", Local.TYPE_NAME+"=="+versioninfo+"=="+mobileInfo);
        params.put("MESSAGE",errorinfo);
        params.put("SCHOOLID", Local.self.centerid);
        HttpUtil.post(params, new JsonHttpResponseHandler() {
            @Override
            public void onFailure(int statusCode, Header[] headers, Throwable throwable, JSONObject errorResponse) {
            }

            public void onSuccess(int statusCode, Header[] headers, JSONArray timeline) {
                ProgressDialogUtils.dismissMyDialog();
                System.out.println(timeline.toString());

            }
        });
        System.out.println("信息发送了 ");
        
        return true;
    }

如何调用?

在Application中

        MyCrashHandler handler = MyCrashHandler.getInstance();
        handler.init(getApplicationContext());
        Thread.setDefaultUncaughtExceptionHandler(handler);

另外一些辅助性的代码

    /**
  * 获取错误的信息 
  * @param arg1
  * @return
  */
 private String getErrorInfo(Throwable arg1) {
  Writer writer = new StringWriter();
  PrintWriter pw = new PrintWriter(writer);
  arg1.printStackTrace(pw);
  pw.close();
  String error= writer.toString();
  return error;
 }
 /**
  * 获取手机的硬件信息 
  * @return
  */
 private String getMobileInfo() {
  StringBuffer sb = new StringBuffer();
  //通过反射获取系统的硬件信息 
  try {
   Field[] fields = Build.class.getDeclaredFields();
   for(Field field: fields){
    //暴力反射 ,获取私有的信息 
    field.setAccessible(true);
    String name = field.getName();
    String value = field.get(null).toString();
    sb.append(name+"="+value);
    sb.append("\n");
   }
  } catch (Exception e) {
   e.printStackTrace();
  }
  return sb.toString();
 }
 /**
  * 获取手机的版本信息
  * @return
  */
 private String getVersionInfo(){
  try {
   PackageManager pm = context.getPackageManager();
    PackageInfo info =pm.getPackageInfo(context.getPackageName(), 0);
    return  info.versionName;
  } catch (Exception e) {
   e.printStackTrace();
   return "版本号未知";
  }
 }
    原文作者:阎炎盐
    原文地址: https://www.jianshu.com/p/4a0593cb8673
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞