AndroidMultidex热修复CLASS_ISPREVERIFIED问题解决方案-1

享学课堂特邀作者:周周
转载请声明出处!

前言

上文Android热修复主流方案盘点 中,提到了4种比较出名的热修复方案,

  • 腾讯Qzone超级补丁的multidex方案,
  • 腾讯Tinker的dexdiff方案,
  • 阿里andFix纯native方法指针重定向方案(已废弃,因为有了新的替代方案 sophix ),
  • 美团的robustinstantRun方案。

然而,在android多版本的兼容上,这些热修复方案多多少少存在一些问题。
本文思路来源为两篇官方技术博文:
安卓App热补丁动态修复技术介绍
Android N混合编译与对热补丁影响解析
可惜大佬发文一般人看不懂,所以我重新解读一下,更通俗易懂地展示这两个坑的解决方案.

正文大纲

  • CLASS_ISPREVERIFIED兼容问题
  • Android N混合编译兼容问题

正文

CLASS_ISPREVERIFIED 兼容问题

Demo地址:https://github.com/18598925736/HotUpdateDemo/tree/4.4_crash_solution

问题描述

一句话描述问题:

在apk安装的时候,Dalvik虚拟机如果发现 一个类A它所引用的其他类,和它自己都处于同一个dex文件内部,那么类A就会被打上一个 CLASS_ISPREVERIFIED 标记,从而提高性能。那么按照这个思路,如果类A引用了一个有bug的类Util,然后我们用multidex热修复方案给他推了一个patch.dex,然后重启修复,这个类已经被打上了标记,但是重启app之后,它所引用的类Util 此时和它又不处于一个dex内(新的Util类在patch.dex内)。此时,起了一个冲突,既打上了标记,又发现不处于一个dex内的引用类,程序就会报错。

CLASS_ISPREVERIFIED 分4个单词 class , is , pre verified , 是否被预先校验

此问题只会出现在Dalvik虚拟机之下(4.4 sdk19 以下默认使用dalvik,5.0 sdk 21 以后便默认使用art虚拟机),art不会有类似问题。所以可以认为此问题只出现在**5.0以下(不含5.0)**的机器上.

问题演示

我使用的是上一篇文章的 Android Muitldex热更新修复方案原理demo
下载之后,直接运行在SDK 19 android4.4的模拟器上。
这是一个已经加入了补丁包fix.dex的demo工程。
当你直接运行,会发现程序崩溃,报错如下:
大概意思就是 有一个类的引用预先校验了,但是没有找到预想中的实现。这就是由于 被打上了CLASS_ISPREVERIFIED标记之后又执行了补丁修复,造成冲突。

解决方案

既然问题的根源在于 引用Util的A类被打上了 CLASS_ISPREVIRIFIED标记,那么有没有办法让这些类不被打上标记呢?

思考:

:如何防止我们源代码中所有的类被打上CLASS_ISPPREVERIFIED标记?
答:
理论上,一个android工程中所有的java类(除了Application之外)都有可能需要热修复。如果让这些类都去引用一个另一个dex文件之下的class,就能防止在dex解析的时候被打CLASS_ISPPREVERIFIED标记。
但是这样有一个弊端,就是 CLASS_ISPPREVERIFIED带来的性能提

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
关于64 k引用限制 Android应用程序(APK)在Dalvik可执行文件的形式包含可执行的字节码文件(DEX)文件,其中包含已编译的代码来运行你的应用程序。Dalvik可执行规格限制一个Dex文件包含65536个方法:包括Android框架方法、Library方法的总数、和你自己的代码方法总数。因为65536等于64×1024,这一限制被称为“64k引用限制”。 这个极限就要求我们配置应用程序的构建过程,需要生成多个DEX文件,所以称为multidex 配置。 分析原因与注意事项 解决方法分Android 5.0及以上系统和5.0以下系统怎么做。客官们不要着急,先看我一个个分析原因,毕竟我要装下逼哈哈。 一、Android 5.0以下的版本 Android 5.0(API leve 21)之前的系统使用Dalvik执行应用程序代码。默认情况下,Dalvik限制一个apk只有一个Dex文件。为了绕过这个限制, 我们可以使用multidex support library,它成为我们APK的主要DEX文件的一部分,负责管理我们APK访问其他DEX文件和代码。 注意: 如果咱的项目minSdkVersion是20或更低,运行到Android 4.4(API leve 20)或者更低版本的设备上时需要禁用AndroidStudio的即时运行 二、Android 5.0和更高版本 Android 5.0(API leve 21)和更高的系统使用runtime是ART ,原生支持从应用的apk文件加载多个DEX文件。ART在安装应用时预编译应用程序,会扫描多个classes(..N).dex文件编译成一个.oat的文件。更多Android5.0 runtime的更多信息,请参见即时运行-instant-run。 注意: 如果你使用即时运行 , AndroidStudio自动配置你的应用程序,你应用程序的minSdkVersion应该设置为21或更高。因为即时只工作在你APP的Debug版本,你任然需要配置你的release版本构建时用multidex避免64k的限制。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值