Android去除烦人的闪退Dialog
2016-04-11 15:28
344 查看
背景
安卓应用闪退后总会出现一个“抱歉,App已经停止运行”的弹窗,这样的用户体验并不好。很多大厂的App都去除了这个弹窗,因此本文主要介绍如何去除默认闪退弹窗,以及在闪退时做一些必要的善后工作。
老规矩,在节目开始之前,先来一个搞笑段子:
又一次坐火车,我坐的是三人一排的那种,我的旁边是一个中年大叔,大叔旁边是一个漂亮的妹子。
我寻思着想找妹子搭搭讪,就对大叔说:“叔叔,我们换个位子行吗?我和她是朋友。”大叔瞥了我一眼,淡淡地说道:“我是他爸。”
UnCaughtExceptionHandler
UnCaughtExceptionHandler能够在Thread遇到未catch住的Exception而终止前做一些善后工作。但是它无法阻止线程停止运行,线程最后还是要退出。
去除Dialog
Android系统默认设置了一个UnCaughtExceptionHandler,而弹出闪退弹窗的工作就是在这个handler做的。所以如果要去除弹窗,只要实现一个UnCaughtExceptionHandler并替换掉系统默认的就可以了,代码如下。
以上的替换UnCaughtExceptionHandler的工作是在Application中统一做的,当然你也可以在每一个Activity中做。对于单个Activity还好,当Activity很多的时候就必需实现一个BaseActivity,在BaseActivity中替换,其它Activity要集成BaseActivity。
必要的善后工作
为了处理闪退,提升用户体验,有必要做一些善后工作,主要有几条罗列如下:
异常上报
可以采用邮件或者通过服务器接口上传的方式。两者各有优缺点,邮件方式开发简单,但需要用户额外操作,用户体验较差。如果用上传服务器方式,因为在UnCaughtExceptionHandler中不能打开一个新的线程,所以只能同步请求,在网络情况不好的时候花费时间会较长而阻塞运行。也可能因为网络原因而上报失败。当然总体下来还是上传服务器好一点。具体实现留给读者。
记录日志
将闪退信息存储到文件系统中。不能存到SharedPreferences中,因为打开SP需要使用一个新的线程(Android内部实现),而这在UnCaughtExceptionHandler中,这是不被允许的。
重新打开App
可以在UnCaughtExceptionHandler中重新打开App或者弹出自定义弹窗。
注意setFlags这一步是必需的,因为使用的Context是App的Context,所以必需打开一个新的任务队列,否则打开Activity无法生效,如果你替换Handler是在Activity做的,拿到的Context是Activity的Context,则无需这一步。
注意事项
最主要的注意点我之前已经提到,不要在UnCaughtExceptionHandler中新开一个线程,会抛出异常。
虽然说正式的商业App都是经过专业测试团队测试的,不会经常crash,但是谁也不能保证没有bug,万一出现crash,这个做法还是可以提升不少用户体验的。
http://sixwolf.net/blog/2016/04/11/Android%E5%8E%BB%E9%99%A4%E7%83%A6%E4%BA%BA%E7%9A%84%E9%97%AA%E9%80%80%E5%BC%B9%E7%AA%97/
本期节目就到这里,感谢大家的收看,下期再见~
安卓应用闪退后总会出现一个“抱歉,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中,这是不被允许的。
重新打开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中新开一个线程,会抛出异常。
虽然说正式的商业App都是经过专业测试团队测试的,不会经常crash,但是谁也不能保证没有bug,万一出现crash,这个做法还是可以提升不少用户体验的。
http://sixwolf.net/blog/2016/04/11/Android%E5%8E%BB%E9%99%A4%E7%83%A6%E4%BA%BA%E7%9A%84%E9%97%AA%E9%80%80%E5%BC%B9%E7%AA%97/
本期节目就到这里,感谢大家的收看,下期再见~
相关文章推荐
- android studio 改编译区背景色
- Android获取指定应用,单独应用的流量统计
- Android - Parcel & Parcelable
- android权限大全 uses-permission
- android开发之SearchView
- Android图片验证码的实现
- android 文件存储调试细节(小米系统)
- Android事件机制
- 脚本安装APK至Android手机
- activity被回收之保存数据
- Android-->无障碍服务(AccessibilityService)开发指南(多用于抢红包,添加附近好友等功能)
- android 开发 命名规范
- Android实现慕课网引导页导航效果
- 弄明白Android 接口回调机制
- Android自定义控件:进度条的四种实现方式(Progress Wheel的解析)(源码 + Demo)
- Android 自定义View字母滑动索引
- Android 点击赞时弹出+1向上弹出动画
- AndroidViewPager禁止左滑(右滑)
- Android 图片加载 BitmapFun
- Android 打造万能圆点指示器