Framework层代码变更 push 之后为什么不能生效?

在framework层修改代码之后,将编译好的framework.jar push 到emulator中,为什么不能生效?
这种情况会发生在5.0以后的版本,网上查阅了一些资料之后都没有用,最终实验的结果都是失败的。原因是因为在5.0的版本之后,添加了一个优化机制,能够提升用户在更新Android系统之后,重启系统这样的场景中,让系统启动的速度能够提升,包括提升应用的运行速度。涉及到ART虚拟机和Dalvik虚拟机的区别了。

Dalvik: 在运行的时候将字节码翻译成机器码,与平台无关,运行效率低下。
ART: 在运行之前,将字节码翻译成机器码,与平台相关,运行效率高。

在5.0的版本之后,源码环境下的应用编译生成的apk包中不包含classes.dex,而是被dex2oat工具转换成oat目录中的.odex文件。这种事情同样也发生在framework层的代码编译之后,编译之后会在framework.jar的同级目录的arm文件中生成一个boot.odex文件。在没有关闭odex优化的系统中,会去执行这块的代码。

解决办法:
1,如果仅仅只是修改app的代码,那么可以很简单,在编译系统运行emulator之后,到main.mk中,添加如下的代码:

ifeq ($(TARGET_BUILD_VARIANT),eng)
tags_to_install := debug eng

## add this option to close dex_preopt
WITH_DEXPREOPT := false

ifneq ($(filter ro.setupwizard.mode=ENABLED, $(call collapse-pairs, $(ADDITIONAL_BUILD_PROPERTIES))),)
  # Don't require the setup wizard on eng builds
  ADDITIONAL_BUILD_PROPERTIES := $(filter-out ro.setupwizard.mode=%,\
          $(call collapse-pairs, $(ADDITIONAL_BUILD_PROPERTIES))) \
          ro.setupwizard.mode=OPTIONAL
endif

接下来所有app 在mm编译之后,apk包中的classes.dex文件就不会消失了。

2,如果是编译系统服务,或者framework层的代码,那么这里要特别注意了,这里就不能在系统编译后再去到main.mk中去设置上面的选项了,要在系统编译之前就设定好。这里我趟过坑。在网上找了很多,很多都说需要替换boot.odex文件,将整个arm的目录替换掉。但是不行,无效。后面我经过思考之后,重新编译来验证我的猜想,结果却是我的这种方法是没有错的。可能在编译之后,系统就开启了这个设置,不管你framework.jar编译后内部是否带有字节码,系统都不会去执行这块的代码,而且系统也不会允许你去覆盖arm 文件下的两个文件。系统都是从/system/framework/arm/目录中去读取两个机器码文件来执行代码。所以才导致push进去的修改后的framework代码无效。

你可能感兴趣的:(Framework层代码变更 push 之后为什么不能生效?)