Android去除烦人的默认闪退Dialog

作者:lijiao 时间:2022-07-16 19:56:14 

安卓应用闪退后总会出现一个“抱歉,App已经停止运行”的弹窗,这样的用户体验并不好。很多大厂的App都去除了这个弹窗,因此本文主要介绍如何去除默认闪退弹窗,以及在闪退时做一些必要的善后工作。

UnCaughtExceptionHandler
UnCaughtExceptionHandler能够在Thread遇到未catch住的Exception而终止前做一些善后工作。但是它无法阻止线程停止运行,线程最后还是要退出。


Thread.setDefaultUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() {
  @Override
  public void uncaughtException(Thread thread, Throwable ex) {
   System.exit(1);
  }
 });

去除Dialog
Android系统默认设置了一个UnCaughtExceptionHandler,而弹出闪退弹窗的工作就是在这个handler做的。所以如果要去除弹窗,只要实现一个UnCaughtExceptionHandler并替换掉系统默认的就可以了,代码如下。


public class App extends Application {

@Override
public void onCreate() {
 super.onCreate();
 Thread.setDefaultUncaughtExceptionHandler(new MyUnCaughtExceptionHandler());
}

class MyUnCaughtExceptionHandler implements Thread.UncaughtExceptionHandler{

@Override
 public void uncaughtException(Thread thread, Throwable ex) {
  ex.printStackTrace();
  // do some work here

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

以上的替换UnCaughtExceptionHandler的工作是在Application中统一做的,当然你也可以在每一个Activity中做。对于单个Activity还好,当Activity很多的时候就必需实现一个BaseActivity,在BaseActivity中替换,其它Activity要集成BaseActivity。

必要的善后工作
为了处理闪退,提升用户体验,有必要做一些善后工作,主要有几条罗列如下:

异常上报
可以采用邮件或者通过服务器接口上传的方式。两者各有优缺点,邮件方式开发简单,但需要用户额外操作,用户体验较差。如果用上传服务器方式,因为在UnCaughtExceptionHandler中不能打开一个新的线程,所以只能同步请求,在网络情况不好的时候花费时间会较长而阻塞运行。也可能因为网络原因而上报失败。当然总体下来还是上传服务器好一点。具体实现留给读者。

记录日志
将闪退信息存储到文件系统中。不能存到SharedPreferences中,因为打开SP需要使用一个新的线程(Android内部实现),而这在UnCaughtExceptionHandler中,这是不被允许的。

闪退三次清除数据
很多时候是由于后台返回数据错误导致的闪退。如果这些数据被缓存下来,那么用户即使再次打开还是会发生闪退,这时候就只能通过重装或者清除数据的方式才能解决闪退问题,用户体验十分不好。所以在多次闪退后自动清除缓存数据十分必要。具体实现可以参考我的另一篇博客Android实现多次闪退清除数据。不过该博客中使用的是ACRA,一个对UnCaughtExceptionHandler再次封装的开源项目,读者可以将ACRA替换为UnCaughtExceptionHandler来实现。

重新打开App
可以在UnCaughtExceptionHandler中重新打开App或者弹出自定义弹窗。


class MyUnCaughtExceptionHandler implements Thread.UncaughtExceptionHandler{

@Override
 public void uncaughtException(Thread thread, Throwable ex) {
  ex.printStackTrace();

Intent intent = new Intent(App.this, MainActivity.class);
  intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
  App.this.startActivity(intent);

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

注意setFlags这一步是必需的,因为使用的Context是App的Context,所以必需打开一个新的任务队列,否则打开Activity无法生效,如果你替换Handler是在Activity做的,拿到的Context是Activity的Context,则无需这一步。

注意事项
最主要的注意点我之前已经提到,不要在UnCaughtExceptionHandler中新开一个线程,会抛出异常。

标签:Android,默认闪退,Dialog
0
投稿

猜你喜欢

  • SpringBoot消息国际化配置实现过程解析

    2023-05-16 01:19:22
  • Java中常用缓存Cache机制的实现

    2023-05-27 23:32:22
  • java开发中使用IDEA活动模板快速增加注释的方法

    2021-09-25 20:42:24
  • Android用动画显示或隐藏视图

    2023-08-05 20:07:25
  • Android Studio实现简易进制转换计算器

    2023-09-17 04:19:29
  • Android Studio 代码导航快捷键

    2023-09-28 09:58:11
  • 全面分析Java文件上传

    2021-12-09 13:22:52
  • 图文精讲java常见分布式事务理论与解决方案

    2023-05-22 19:50:10
  • JAVA JDK8 List分组的实现和用法

    2023-11-26 09:56:11
  • 详解Java中的日期类

    2022-08-27 17:14:03
  • android I/0流操作文件(文件存储)

    2021-11-13 19:42:37
  • 详解Spring Cloud Eureka多网卡配置总结

    2023-11-09 07:33:15
  • Java截取字符串的几种方法示例

    2023-11-29 12:36:32
  • ReentrantLock源码详解--公平锁、非公平锁

    2023-04-22 17:18:56
  • Java的Socket网络编程基础知识入门教程

    2021-11-19 10:10:37
  • 使用Feign扩展包实现微服务间文件上传

    2023-04-28 01:04:31
  • Android开发实现ListView异步加载数据的方法详解

    2022-03-26 02:31:57
  • Android下拉刷新以及GridView使用方法详解

    2022-12-26 18:01:24
  • 使用java基础类实现zip压缩和zip解压工具类分享

    2021-11-23 08:03:41
  • C# Aspose.Words 删除word中的图片操作

    2023-07-29 12:01:43
  • asp之家 软件编程 m.aspxhome.com