Android启动保护模式实践
来源:互联网 发布:数据挖掘 教学大纲 编辑:程序博客网 时间:2024/05/22 00:05
一般初始化app的第三方类库或者so库操作都会放在Application的onCreate()方法里,因为此时Application才算创建完成,在这里初始化是自然而然的。由于我们的应用是直播类,音视频操作和接口调用是在jni层处理,初始化这两个so库也是放在Application的onCreate里,但前段时间发生了一次偶发性但非常严重的bug。当时是服务端接口升级出现问题,导致处理接口的so库一初始化就崩溃。正式发布的应用出现这种问题可以说是致命的,用户打开你的应用,连首页都没见到就crash,影响特别不好。且由于检测App升级是在首页初始化才调用,导致后台配置接口让用户强制升级解决问题都没办法,束手无此。
通常来讲,再烂的应用在正常的条件下都能保证正常打开,但在一些特殊条件下是有可能导致应用重复崩溃的,例如:
- 数据库损坏:在日常使用如异常退出、断电,或者错误的操作
- 文件损坏:处理文件时如果没有 @try…catch,损坏文件会抛出 IOException导致crash
- 网络返回数据处理异常:比如预期返回数组,但实际返回了字典,java.lang.ClassCastException
- 代码 bug:当必 crash 的代码出现在启动关键路径中,就会导致连续闪退。
以上这些条件如果测试到位,能大大减少出现的概率,只不过程序的世界并不存在100%的情况,我们要做的事是当出现异常时,我们能及时甚至无感的将bug修复掉。
经分析,由于我们app使用数据库及文件的地方不多,媒体和接口的so库导致问题的概率比较大,我们重点考虑修复这种情况,当多次初始化so库崩溃时,能让app去下载新的so库并加载新的so库。
想要做到以上这点,涉及到两个问题,检测及更新。
检测
检测有两种办法:
1、 崩溃记录法:使用bugly之类的检测奔溃的sdk,在特定时间里(比如5s),检测到崩溃后就记录一次,连续三次都在5s内崩溃就延迟所有初始化,走修复流程;期间有一次正常运行超过5s计数清0;
2、时间记录法:在特定的时间内(比如5s),如果app退出,就记录一次,然后设定一个阀值(比如3次),达到阀值就走修复流程。如果达到阀值前有一次超过5s,计数就清0;
其实这两者有点相似,区别是第1种需要检测崩溃,第2种不用,相应的第1种更复杂但不会误触发,第2种简单但有概率误触发。
我首先用Bugly实践第一种方法,结果发现虽然Bugly有检测到崩溃回调的函数,但这个回调处理是在Java层,而jni有些崩溃会导致jvm直接退出,如果在java层接受回调肯定是收不到的。jni层的崩溃只能在jni层检测,由于我们的so库是多个平台公用,专为Android端增加此功能的阻力较大,这种方式只好放弃。
于是我们采用了第2种方式,时间记录法,下面是流程图:
更新
更新的前提是进入修复流程,修复流程是不初始化任何第三方so库及其他正常需要初始化的类,等到修复完才回到正常流程。下面是流程图:
上面的流程是比较简单的,不过需要解决两个问题:
1、 下载so库时由于欢迎页都没初始化,怎么显示交互,总不能一片白色,让用户以为ARN吧?
我们在下载so库时,动态把ProgressBar加进android.R.id.content
//添加进度条mDownloadPb = (ProgressBar)LayoutInflater.from(mContext).inflate(R.layout.pb_update_so,(ViewGroup) ((Activity)mContext).findViewById(android.R.id.content)).findViewById(R.id.pb_update_so);
以下是下载so库时的截图:
2、下载成功后怎么让程序使用最新的so库
首先本地得保存你每次发布时so库的版本号,以及每次你更新完需要保存更新下来so库的版本号,每次load之前都先对比一下,如果下载下来的版本号更新及文件存在的话,就判定为新的so库,加载此库即可。
if (BuildConfig.LIB_VERSION < PreferenceHelper.getInstance().getLibVersion()) { File soPath = new File(FileUtil.getSoLibPath(),LIB_FILE_NAME)); if (FileUtil.fileIsExists(soPath)) { System.load(soPath.getAbsolutePath()); } else { System.loadLibrary(PROTOCOL_LIB_NAME); }} else { System.loadLibrary(PROTOCOL_LIB_NAME);}
注:本文的设计思想参考自微信读书的文章
- Android启动保护模式实践
- android启动模式实践
- 第一次启动保护模式
- 第二次启动保护模式
- 第三次启动保护模式
- 启动保护模式的程序
- Android资源混淆保护实践
- 学习笔记--实践认识保护模式
- Android 基础 -- 生命周期和启动模式实践总结
- 美团Android资源混淆保护实践
- 美团Android资源混淆保护实践
- 美团Android资源混淆保护实践
- 美团Android资源混淆保护实践
- 美团Android资源混淆保护实践
- 美团Android资源混淆保护实践
- 美团Android资源混淆保护实践
- 美团Android资源混淆保护实践
- 美团Android资源混淆保护实践
- mysql数据类型
- jsonp实现跨域请求
- android studio提示failed to create jvm和could not reserve enough space for object heap的解决方法
- 图像金字塔分层算法
- WCF 简单架构(一) 契约和客户端
- Android启动保护模式实践
- html+css+js的小时钟
- mac版HBuilder java路径问题解决
- C语言中.h和.c文件解析(很精彩)
- 如何在ElementaryOS下安装中文输入法
- Bayer转RGB
- caffe编译中的python问题
- pg批量修改字段内容
- Java程序员进化为架构师掌握的知识