原文地址:http://blog.chinaunix.net/uid-29728680-id-5576422.html
[FAQ12138]Prebuilt APK提取odex
2014-07-10
FAQs 48 of 88如何解決修改custom_Memorydevice.h中的宏定義而導(dǎo)致的編譯錯誤為什么user build 的system.img會比eng build 大
內(nèi)容
[DESCRIPTION]
??? odex是從APK中提取出來的可運行文件骗爆,即將APK中的class.dex文件通過dex優(yōu)化過程將其優(yōu)化生成odex文件單獨存放碰煌。
??? 如果沒有odex位隶,系統(tǒng)需要在開機過程中從APK內(nèi)提取dex再運行;如果在build過程中預(yù)先提取致盟,可加快系統(tǒng)啟動速度欣除、節(jié)省開機時間路召。
??? 目前的做法:
–??????User?版本會預(yù)先提取有source code的APK的odex文件讳嘱,因為有source code的APK在Android.mk中都會通過include $(BUILD_PACKAGE)來編譯,會調(diào)用到package.mk來提取odex
–??????但User版本不會預(yù)先提取通過prebuilt方式預(yù)置的APK的odex文件虎敦,因為采用prebuilt方式預(yù)置APK是只有APK文件而沒有source code時在Android.mk中通過?include $(BUILD_PREBUILT)預(yù)置APK游岳,代碼中原本的prebuilt.mk中不會提取odex
[KEYWORDS]
??? 預(yù)置APK
??? build提取odex
??? odex
??? prebuilt
[SOLUTION]
??? 實現(xiàn)prebuilt APK提取odex的修改方法如下
??? 修改build/core/prebuilt.mk(以下修改基于KK版本的源碼,JB版本上此部分修改類似)
1.文件最開始部分添加紅色部分
ifneq (true,$(WITH_DEXPREOPT))
LOCAL_DEX_PREOPT :=
else
ifndef LOCAL_DEX_PREOPT
LOCAL_DEX_PREOPT := $(DEX_PREOPT_DEFAULT)
endif
endif
ifeq (false,$(LOCAL_DEX_PREOPT))
LOCAL_DEX_PREOPT :=
endif
ifeq ($(filter APPS,$(LOCAL_MODULE_CLASS)),)
LOCAL_DEX_PREOPT :=
endif
$(info prebuild $(LOCAL_MODULE)==> $(LOCAL_DEX_PREOPT))
... ...
2.添加紅色部分
... ...
ifdef LOCAL_IS_HOST_MODULE
my_prefix := HOST_
LOCAL_DEX_PREOPT :=
else
my_prefix := TARGET_
endif
... ...
3.添加紅色部分
... ...
ifneq ($(filter APPS,$(LOCAL_MODULE_CLASS)),)
ifdef LOCAL_DEX_PREOPT
$(built_module): $(DEXPREOPT_BOOT_ODEXS) | $(DEXPREOPT) $(DEXOPT)
endif
ifeq ($(LOCAL_CERTIFICATE),PRESIGNED)
# Ensure that presigned .apks have been aligned.
$(built_module) : $(my_prebuilt_src_file) |$(ACP)$(ZIPALIGN)
#$(transform-prebuilt-to-target-with-zipalign)
$(transform-prebuilt-to-target)
ifdef LOCAL_DEX_PREOPT
$(hide) rm -f $(patsubst %.apk,%.odex,$@)
$(call dexpreopt-one-file,$@,$(patsubst %.apk,%.odex,$@))
ifneq (nostripping,$(LOCAL_DEX_PREOPT))
$(call dexpreopt-remove-classes.dex,$@)
endif
endif
$(align-package)
else
# Sign and align non-presigned .apks.
$(built_module) : $(my_prebuilt_src_file) | $(ACP) $(ZIPALIGN) $(SIGNAPK_JAR)
$(transform-prebuilt-to-target)
$(sign-package)
#add below
ifdef LOCAL_DEX_PREOPT
$(hide) rm -f $(patsubst %.apk,%.odex,$@)
$(call dexpreopt-one-file,$@,$(patsubst %.apk,%.odex,$@))
ifneq (nostripping,$(LOCAL_DEX_PREOPT))
$(call dexpreopt-remove-classes.dex,$@)
endif
endif
#add upon
$(align-package)
endif
ifdef LOCAL_DEX_PREOPT
built_odex := $(basename $(built_module)).odex
$(built_odex): $(built_module)
endif
else
... ...
說明:
??? (1)user build默認開啟dexopt功能其徙,eng build關(guān)閉胚迫,所以只是build user版本會提取APK的odex文件
??? (2)請務(wù)必不要忘記把預(yù)置的module添加到build/target/product/common.mk(或者[proj].mk)中的PRODUCT_PACKAGES里
(3)只有prebuilt預(yù)置APK時會生效,放置在vendor下拷貝的方式來預(yù)置APK是不會生效的唾那。如一個apk文件放在目錄vendor/mediatek/project_name/artifacts/out/target/product/project_name/system/app下通過拷貝方式來預(yù)置访锻,build過程是不會提取它的odex文件的。