Android 7.0(N)以上版本的JIT问题
原因:
在Android N以后的版本会对频繁使用的app进行jit操作,从而生成app image并更新oat文件。如果app image包含了补丁修改的class,就无法进行热更新。因为app在启动时会把这些类加入到PathClassloader的ClassTable中,系统在查找类时会直接使用base.apk中的class,最终导致修复不成功。不过,只有Android N版本后频繁使用的app会由系统进行jit,所以影响范围并不是非常广。
解决方案:
Sophix 3.1.0以上版本已经自动处理,无需适配。
建议始终更新到 Sophix 最新版本,更加稳定。
在7.0以上版本的手机系统上出现java.lang.Exception: ... abort cold fix异常
在7.0以上版本的手机系统上出现java.lang.Exception: … abort cold fix异常,应用崩溃,一般后面还会报出java.lang.ClassNotFoundException异常
原因:
在Android N以后的版本会对频繁使用的app进行jit操作,从而生成app image并更新oat文件。如果app image包含了补丁修改的class,就无法进行热更新。因为app在启动时会把这些类加入到PathClassloader的ClassTable中,系统在查找类时会直接使用base.apk中的class,最终导致修复不成功。
因此我们在7.0以上版本做了特殊处理来避免jit的影响,但是这种处理需要保证在Sophix初始化前不用到其他自定义类。另外有可能是冷启动修复在运行时开启了Instant Run或者安装包与打补丁的旧包不一致导致。
解决方案:
首先确保Instant Run是关闭状态,并且安装在手机上的包与打补丁的旧包一致。
解决方法和4.4的pre-verify问题一样。Sophix初始化放在Application最前面,同时在初始化前的代码都要使用系统类而不使用自定义类(如自定义的logutil等)。
具体就是把initialize写到attachBaseContext里面,但query还是在onCreat的最前面;如果有用到MultiDex,直接继承Application,在attachBaseContext里写MultiDex.install(base),然后在onCreat的最前面initialize和query,如果还会出现这个崩溃,把initialize写到attachBaseContext的MultiDex.install(base)后面,但query还是在onCreat的最前面。
在4.x的手机系统上可能出现的崩溃问题的解决方法
原因:
在4.x的系统上出现IllegalAccessException:class ref in pre-verified异常,应用崩溃
解决方案:
Sophix初始化在Application最前面,同时在初始化前的代码都要使用系统类而不使用自定义类(如自定义的logutil等)。
具体就是把initialize写到attachBaseContext里面,但query还是在onCreat的最前面;如果有用到MultiDex,直接继承Application,在attachBaseContext里写MultiDex.install(base),然后在onCreat的最前面initialize和query,如果还会出现这个崩溃,把initialize写到attachBaseContext的MultiDex.install(base)后面,但query还是在onCreat的最前面。