应用升级时如果替换了通知等 RemoteView 中的资源文件,则可能会导致新的升级包资源 id 发生变动,在部分机型上体现为android.app.RemoteServiceException
。崩溃日志大致如下:
|
|
前段时间升级直接导致 crash 收集平台被该 bug 刷屏,而测试过程又一次都没有复现。StackOverFlow 上也没有太好的解决方案。这里探索了一种固化资源 id 的解决方案,线上验证也是可行的,bug率明显下降。但是另一种类似的cannot expand view
还未能解决。
通过反编译可以发现,Android App 会在 res/values/public.xml
里存储所有的资源文件名到资源文件 id 的映射关系。如果在编译前手动添加部分资源的 id 到 public.xml 下,那么这些资源的 id 就得以固化,升级以及添加修改资源都不会对这些 id 产生影响。此外,res/values/ids.xml
也起到了类似作用,只不过仅覆盖 id 资源。
因此,解决思路应该是反编译 Apk 包,获得最新的public.xml
,讲所有RemoteView
涉及到的资源文件,包括string, dimen, drawable, id, layout
等,提取出来并保存在项目源码中的res/values/public.xml
和res/values/ids.xml
文件中。
注意:Gradle 自 1.3.0 以后版本编译时会默认忽略本地的 public.xml
文件,因此还需要添加 Gradle 脚本使 public.xml
生效。打开 app 的 build.gradle
文件,在最后添加如下脚本 (参考连接中也提到了利用 Gradle 插件的解决方案):
|
|
— Update
如果需要对submodule
中的资源也增加id固化,则可以在上面代码['res']
中增加相应资源路径即可。
参考: