LOCAL_PREBUILT_STATIC_JAVA_LIBRARIES
LOCAL_PREBUILT_LIBS
LOCAL_STATIC_JAVA_LIBRARIES
Android中可能会用到第三方的软件包,这包括Java包.jar和Native包.so。jar包既可通过Eclipse开发环境集成,也可通过编译源码集成,看你的工作环境。
假定自己开发的程序为MyMaps,需要用到BaiduMaps的库,包括baidumapapi.jar和libBMapApiEngine_v1_3_1.so。
一、Eclipse中集成第三方jar包及.so动态库
MyMaps工程下创建目录libs以及libs/armeabi,把baidumapapi.jar放在的libs/目录下,把libBMapApiEngine_v1_3_1.so放在libs/armeabi/下。
Eclipse中把第三方jar包baidumapapi.jar打包到MyMaps的步骤:
1. 右击工程,选择Properties;
2. JavaBuild Path,选择Libraries;
3. Libraries页面点击右面按钮“Add Library…”;
4. 选择“User Library”,点击“Next”;
5. 点击“User Libraries”按钮;
6. 在弹出界面中,点击“New…”;
7. 输入“User library name”,点击“OK”确认;
8. 返回之后,选择刚刚创建的User library,右面点击“AddJARs”;
9. 选择MyMaps/libs/下的baidumapapi.jar;
10. 确认,返回。
这样,编译之后,该jar包就会被打进MyMaps.apk中,libBMapApiEngine_v1_3_1.so也被打包在lib/armeabi/中。
程序运行过程中,libBMapApiEngine_v1_3_1.so被放在/data/data/<yourAppPackage>/lib/下,加载动态库时系统会从程序的该lib/目录下查找.so库。
二、源码中集成第三方集成jar包及.so动态库
Android源码中MyMaps放在packages/apps下。
MyMaps下创建目录libs以及libs/armeabi,并把baidumapapi.jar放在libs/,把libBMapApiEngine_v1_3_1.so放在libs/armeabi。
2.1 修改Android.mk文件
Android.mk文件如下:
1. LOCAL_PATH:= $(call my-dir)
2. include $(CLEAR_VARS)
4. LOCAL_MODULE_TAGS := optional
6. LOCAL_STATIC_JAVA_LIBRARIES := libbaidumapapi
8. LOCAL_SRC_FILES := $(call all-subdir-java-files)
10. LOCAL_PACKAGE_NAME := MyMaps
12. include $(BUILD_PACKAGE)
13.
14. ##################################################
15. include $(CLEAR_VARS)
17. LOCAL_PREBUILT_STATIC_JAVA_LIBRARIES :=libbaidumapapi:libs/baidumapapi.jar
18. LOCAL_PREBUILT_LIBS :=libBMapApiEngine_v1_3_1:libs/armeabi/libBMapApiEngine_v1_3_1.so
19. LOCAL_MODULE_TAGS := optional
20. include $(BUILD_MULTI_PREBUILT)
21.
22. # Use the following include to make our testapk.
23. include $(callall-makefiles-under,$(LOCAL_PATH))
1 集成jar包
LOCAL_STATIC_JAVA_LIBRARIES 取jar库的别名,可以任意取值;
LOCAL_PREBUILT_STATIC_JAVA_LIBRARIES指定prebuiltjar库的规则,格式:别名:jar文件路径。注意:别名一定要与LOCAL_STATIC_JAVA_LIBRARIES 里所取的别名一致,且不含.jar;jar文件路径一定要是真实的存放第三方jar包的路径。
编译用BUILD_MULTI_PREBUILT
2 集成.so动态库
LOCAL_PREBUILT_LIBS指定prebuilt so的规则,格式:别名:so文件路径。注意:别名一般不可改变,特别是第三方jar包使用.so库的情况,且不含.so;so文件路径一定要是真实的存放第三方so文件的路径。
编译拷贝用BUILD_MULTI_PREBUILT。
2.2 加入到GRANDFATHERED_USER_MODULES
在文件user_tags.mk中,把libBMapApiEngine_v1_3_1加入到GRANDFATHERED_USER_MODULES中
1. GRANDFATHERED_USER_MODULES += \
2. … \
3. libBMapApiEngine_v1_3_1
user_tags.mk可以是build/core下的,也可以是$(TARGET_DEVICE_DIR)下的,推荐修改$(TARGET_DEVICE_DIR)下的。
2.3 编译结果
MyMaps.apk编译生成在out/target/product/<YourProduct>/system/app/下;
libBMapApiEngine_v1_3_1.so放在out/target/product/<YourProduct>/system/lib/下,这也是系统加载动态库时搜索的路径。
附上自己写的android.mk文件一个
LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)
LOCAL_STATIC_JAVA_LIBRARIES := lib3party
LOCAL_SRC_FILES := $(call all-subdir-java-files
LOCAL_PACKAGE_NAME := OnlineDownload
include $(BUILD_PACKAGE)
include $(CLEAR_VARS)
LOCAL_PREBUILT_STATIC_JAVA_LIBRARIES :=lib3party:libs/android-support-v4.jar
include $(BUILD_MULTI_PREBUILT)
当需要加载多个jar包时,只需要按照mk文件规则,在定义变量的地方先空格,然后输入”\”符号,然后回车,然后输入jar包别名就行,附上编译通过的自己写的导入多个jar包的mk文件
LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)
LOCAL_STATIC_JAVA_LIBRARIES := libname1 \
libname2 \
libname3
LOCAL_SRC_FILES := $(callall-subdir-java-files)
LOCAL_PACKAGE_NAME := OnlineDownload
include $(BUILD_PACKAGE)
include $(CLEAR_VARS)
LOCAL_PREBUILT_STATIC_JAVA_LIBRARIES :=libname1:libs/android-support-v4.jar \
libname2:libs/commons-net-1.2.2.jar \
libname3:libs/jakarta-oro-2.0.8.jar
include $(BUILD_MULTI_PREBUILT)
LOCAL_MODULE_CLASS and LOCAL_MODULE_PATH
3include $(CLEAR_VARS)
4LOCAL_MODULE := receiver_filter_policy.xml
5LOCAL_MODULE_TAGS := optional
6LOCAL_MODULE_CLASS := ETC
7LOCAL_MODULE_PATH := $(TARGET_OUT_ETC)
8LOCAL_SRC_FILES := $(LOCAL_MODULE)
9include $(BUILD_PREBUILT)
./product/flounder32/obj/ETC/receiver_filter_policy.xml_intermediates
./product/flounder32/obj/ETC/receiver_filter_policy.xml_intermediates/receiver_filter_policy.xml
./product/flounder32/system/etc/receiver_filter_policy.xml
5include $(CLEAR_VARS)
6LOCAL_MODULE := appops
7LOCAL_SRC_FILES := appops
8LOCAL_MODULE_CLASS := EXECUTABLES
9LOCAL_MODULE_TAGS := optional
10include $(BUILD_PREBUILT)
./product/flounder32/obj/EXECUTABLES/appops_intermediates
./product/flounder32/obj/EXECUTABLES/appops_intermediates/appops
./product/flounder32/system/bin/appops
5include $(CLEAR_VARS)
6LOCAL_MODULE := appops
7LOCAL_SRC_FILES := appops
8LOCAL_MODULE_CLASS := EXECUTABLES
9LOCAL_MODULE_TAGS := optional
10include $(BUILD_PREBUILT)
./product/flounder32/obj/EXECUTABLES/appops_intermediates
./product/flounder32/obj/EXECUTABLES/appops_intermediates/appops
./product/flounder32/system/bin/appops
3include $(CLEAR_VARS) 4 5LOCAL_MULTILIB := 32 6LOCAL_SRC_FILES_arm := armeabi/libAlphaInputWrapper.so 9 10LOCAL_MODULE := libAlphaInputWrapper 11LOCAL_MODULE_CLASS := SHARED_LIBRARIES 12LOCAL_MODULE_SUFFIX := .so 13LOCAL_MODULE_TAGS := optional 14 15include $(BUILD_PREBUILT) ./product/flounder32/obj/lib/libAlphaInputWrapper.so ./product/flounder32/obj/SHARED_LIBRARIES/libAlphaInputWrapper_intermediates ./product/flounder32/obj/SHARED_LIBRARIES/libAlphaInputWrapper_intermediates/LINKED/libAlphaInputWrapper.so ./product/flounder32/obj/SHARED_LIBRARIES/libAlphaInputWrapper_intermediates/PACKED/libAlphaInputWrapper.so ./product/flounder32/system/lib/libAlphaInputWrapper.so ./product/flounder32/symbols/system/lib/libAlphaInputWrapper.so
In fireos/prebuilts/middleware/h2clientservice/prebuilts/apk/debug/Android.mk
3# the debug apps are only effective for eng build 4ifneq (,$(filter debug,$(FIREOS_PREBUILT_INSTALL))) if in userdebug build, continue 5 6# enum all the .apk files immediately below current directory 7debug_apps := $(notdir $(wildcard $(LOCAL_PATH)/*.apk)) search for apk file in current folder 8 9# all the debug apps will be signed with the key specified by LOCAL_CERTIFICATE 10# regardless of the original key signed the package with. 11define _add_debug_apps 12include $$(CLEAR_VARS) 13LOCAL_MODULE := $(basename $1) 14LOCAL_SRC_FILES := $1 15LOCAL_MODULE_TAGS := optional 16LOCAL_CERTIFICATE := $(FIREOS_LOCAL_CERTIFICATE_OVERRIDE) 17LOCAL_MODULE_SUFFIX := $$(COMMON_ANDROID_PACKAGE_SUFFIX) 18LOCAL_MODULE_CLASS := APPS 19LOCAL_PRIVILEGED_MODULE := true 20include $$(BUILD_PREBUILT) 21endef 22 23$(foreach _apk, $(debug_apps), \ 24 $(eval $(call _add_debug_apps,$(_apk)))) For each apk file, call _add_debug_apps function, the parameter is the apk path.25 26local_install_packages += $(basename $(debug_apps)) 27 28debug_apps := 29 30endif # ifneq (,$(filter debug,$(FIREOS_PREBUILT_INSTALL))) ./product/flounder32/obj/APPS/com.amazon.h2clientservice_intermediates ./product/flounder32/system/priv-app/com.amazon.h2clientservice ./product/flounder32/system/priv-app/com.amazon.h2clientservice/com.amazon.h2clientservice.apk In fireos/prebuilts/middleware/h2clientservice/prebuilts/jar/Android.mk19_non_dexed_jar_files := com.amazon.h2contracts.jar 21 22# static jar files must be added manually 23_static_jar_files := 24 25# generate install jar file list 26_install_jar_files := $(filter-out $(_static_jar_files),$(_non_dexed_jar_files)) 27 28 29ifneq ($(strip $(SHOW_COMMANDS)),) 30$(info _non_dexed_jar_files=$(_non_dexed_jar_files)) 31$(info _static_jar_files=$(_static_jar_files)) 32$(info _install_jar_files=$(_install_jar_files)) 33endif 34 35 36include $(CLEAR_VARS) 37LOCAL_PREBUILT_JAVA_LIBRARIES := $(_install_jar_files) 38LOCAL_PREBUILT_STATIC_JAVA_LIBRARIES := $(_static_jar_files) 39include $(BUILD_MULTI_NONDEX_JAVA_LIBRARIES) 40 41local_install_packages += $(basename $(_install_jar_files))
./product/flounder32/obj/JAVA_LIBRARIES/com.amazon.h2contracts_intermediates
./product/flounder32/system/framework/com.amazon.h2contracts.jar
./common/obj/JAVA_LIBRARIES/com.amazon.h2contracts_intermediates As the jar file may be used by other components, so generate intermediates file for future usage.
In fireos/prebuilts/system/apks/debug/com.amazon.dp.contacts/Android.mk
9LOCAL_MODULE_TAGS := optional 17LOCAL_MODULE := com.amazon.dp.contacts 20LOCAL_CERTIFICATE := $(FIREOS_LOCAL_CERTIFICATE_OVERRIDE) 21 26LOCAL_MODULE_CLASS := APPS 27LOCAL_MODULE_SUFFIX := $(COMMON_ANDROID_PACKAGE_SUFFIX) 28LOCAL_PRIVILEGED_MODULE := true 39include $(BUILD_PREBUILT)
./product/flounder32/obj/APPS/com.amazon.dp.contacts_intermediates
./product/flounder32/system/priv-app/com.amazon.dp.contacts
./product/flounder32/system/priv-app/com.amazon.dp.contacts/com.amazon.dp.contacts.apk
In In fireos/packages/apps/Precog/Android.mk8LOCAL_MODULE := precog-api 9LOCAL_MODULE_TAGS := optional 10LOCAL_MODULE_CLASS := JAVA_LIBRARIES 11LOCAL_JAVA_LIBRARIES := fireos.sdk.annotations 12 13LOCAL_SRC_FILES := \ 14 src/main/java/com/amazon/precog/api/FeatureCallback.java \ 21include $(BUILD_JAVA_LIBRARY)
./product/flounder32/obj/JAVA_LIBRARIES/precog-api_intermediates
./product/flounder32/system/framework/precog-api.jar
./common/obj/JAVA_LIBRARIES/precog-api_intermediates
In In fireos/packages/apps/FrankDvrServer/test/Android.mk1LOCAL_PATH:= $(call my-dir) 2include $(CLEAR_VARS) 3 4LOCAL_PACKAGE_NAME := FrankMediaServerTest 5LOCAL_MODULE_TAGS := optional 6LOCAL_CERTIFICATE := platform 7LOCAL_PRIVILEGED_MODULE := true 8LOCAL_PROGUARD_ENABLED := disabled 9LOCAL_DEX_PREOPT := false 10 11LOCAL_SRC_FILES := $(call all-java-files-under, src) 15include $(BUILD_PACKAGE)
./product/flounder32/obj/APPS/FrankMediaServerTest_intermediates
./product/flounder32/system/priv-app/FrankMediaServerTest/FrankMediaServerTest.apk
./common/obj/APPS/FrankMediaServerTest_intermediates
In frameworks/opt/vcard/Android.mk16include $(CLEAR_VARS) 19LOCAL_SDK_VERSION := 9 20 21LOCAL_MODULE := com.android.vcard 22LOCAL_SRC_FILES := $(call all-java-files-under, java) 23 24include $(BUILD_STATIC_JAVA_LIBRARY)
./common/obj/JAVA_LIBRARIES/com.android.vcard_intermediates
WITH_DEXPREOPT
所有的 apk 内包含一个 classes.dex 文件。
在 Dalvik上,apk包里的 dex文件在安装的时候会通过 dexopt 转化成另一个格式,叫odex(Opitimized dex),然后存在 /data/dalvik-cache里面,如:
/data/dalvik-cache/data@app@com.wochacha-1.apk@classes.dex
虽然文件后缀还是 .dex,但是这个dex和apk内的那个已经不一样了。这个文件是针对当前机器的硬件对 dex 文件进行了定制化,也就是说把这个放到别的设备上,不一定能运行。
PS: 在要编译 rom 的时候,如果参数加上 "WITH_DEXPREOPT=true",会在 /system/app/ 下同时生成 .apk 和 .odex 文件(注意,这里后缀又用的 .odex,但实际上和系统在 /data/dalvik-cache/ 下的 .dex文件是一样的)
在 ART上,apk 包里的 dex文件在安装的时候通过 dex2oat,也会生成一个后缀为 .dex 的文件,放在 /data/dalvik-cache中,如:
/data/dalvik-cache/arm/system@app@Bluetooth@Bluetooth.apk@classes.dex
/data/dalvik-cache/arm64/system@vendor@app@ims@ims.apk@classes.dex
这个文件后缀叫 .dex ,但是这个文件又不一样了,这个既不是 dex 也不是 odex,用 dex2jar 的无法进行反编译的。文件格式也完全不同,因为这其实就是一个实打实的 elf文件,这个文件已经可以直接在机器上运行了。
WITH_DEXPREOPT使能编译时生成 OAT,避免第一次开机时编译耗时,但会增大 system分区的空间消耗
DONT_DEXPREOPT_PREBUILTS
使能后,将不会对 Android.mk中包含了 include $(BUILD_PREBUILT)的 Apk进行 oat,例如 Gmail,它很可能会在后期通过商店自行升级,而升级后系统中的 oat文件则没有意义了,但又无法删除,会造成空间的浪费(oat比dex文件要大)
WITH_DEXPREOPT_BOOT_IMG_ONLY
仅仅针对 boot.img进行oat优化(boot.img中包含 boot.art和 boot.oat)
LOCAL_DEX_PREOPT (from DEX_PREOPT_DEFAULT)
value : ture | false | nostripping
可用于各个 Android.mk,对每个 package进行单独配置,当设置为 true时,dex文件将会从 apk中剔除,如果不想剔除可使用 nostripping.
PRODUCT_DEX_PREOPT_BOOT_FLAGS
这里的参数将会传至 dex2oat,控制 boot.img的编译优化行为。
PRODUCT_DEX_PREOPT_DEFAULT_FLAGS
控制除 boot.img 外,其他(如 jar, apk)的 OAT编译行为 例如:
PRODUCT_DEX_PREOPT_DEFAULT_FLAGS := --compiler-filter=interpret-only
$(call add-product-dex-preopt-module-config,services,--compiler-filter=space)
WITH_DEXPREOPT_PIC
ture|false
使能 position-independent code,这样在dex2oat编译生成的 odex文件在运行时将不必再从 /system 下拷贝到 /data/dalvik-cache/ 目录下, 可以节省 /data 空间
WITH_ART_SMALL_MODE
true|false
设置为 true 时,将只编译处于 boot classpath 里的类,其他的均不编译,这样既能加快第一次开机时间,因为大部分必要的类已经编译过了; 同时也能节省不少空间,因为 APP 都未进行编译。缺点是可能损失一性能,这可能要平时觉察不出,但在跑分软件上会有所体现
编译选项的经典配置
为了提高第一次开机速度,WITH_DEXPREOPT是必须使能的,这样则在编译阶段会完成 dex2oat的操作,避免在开机时间去做这个转码,节省了开机时间(6min以上缩短2min内)。
但会引起一个缺点,那就是 apk中还是包含了class.dex(dexopt生成的),同时在对应的apk文件夹中又生成了已经转码成oat的 class.odex(dex2oat生成的),相当于这部分重复,造成了大量的空间浪费。
为了把 apk包里的 class.dex去除,节省空间,可以打开 DEX PREOPT DEFAULT := ture。
然而,这样开机速度是快了,而且节省了不少system空间,但开机后,我们会发现即使在 system中已经存在 class.odex的 apk,第一次开机后还是会在 /data下面生成 class.odex,如data/dalvik-cache/arm64/system@app@Music@Music.apk@classes.dex,这是何解?原来 Google为了提高安全性,在每一台机器开机时都会在之前的机器码加一个随机的偏移量,这个偏移量是随机的,每台机器都不相同,而 data分区下的这些文件就是从 system下的 class.odex加上偏移而来。
A ref: Android预优化那些事
Our preopt solution
We define a variable USE_FIREOS_DEFAULT_DEXPREOPT. User can set it to "true, false, userdata, cache". If not set, we set the value according to the environment.
367ifeq ($(HOST_OS),linux) 368 ifeq ($(TARGET_BUILD_VARIANT),user) 369 # Use the default dexpreopt parameters for user builds. 370 # Not all devices have sufficient space in system for this 371 # configuration to work on other variants. They will either 372 # not dexpreopt at all (like stock AOSP), or make some compromises 373 # to get some benefit from dexpreopt. 374 USE_FIREOS_DEFAULT_DEXPREOPT ?= userdata 375 else # ! ifeq ($(TARGET_BUILD_VARIANT),user) 376 ifeq ($(TARGET_BUILD_VARIANT),userdebug) 377 USE_FIREOS_DEFAULT_DEXPREOPT ?= userdata 378 endif # ifeq ($(TARGET_BUILD_VARIANT),userdebug) 379 endif # ifeq ($(TARGET_BUILD_VARIANT),user) 380endif # ($(HOST_OS),linux) 381 382# Devices that need a minimal dexpreopt configuration, with only boot.art 383# and boot.oat installed in the system partition should also change the 384# default value of DEX_PREOPT_DEFAULT, typically: 385# DEX_PREOPT_DEFAULT := $(USE_FIREOS_DEFAULT_DEXPREOPT) 386# This will cause non-BOOTCLASSPATH jars and platform applications to 387# get compiled to userdata/cache instead of system. The default value is 388# purposely not overridden here because keeping as much precompiled code 389# in system as possible is optimal for overall storage efficiency and for 390# boot time after system OTA and factory reset. 391 392# Preserve documented AOSP behavior: if WITH_DEXPREOPT is false, we don't 393# want to enable any special FireOS dexpreopt behavior. 394ifeq ($(WITH_DEXPREOPT),false) 395 USE_FIREOS_DEFAULT_DEXPREOPT := 396 DONT_DEXPREOPT_PREBUILTS := true 397 DEXPREOPT_PREBUILTS_INSTALL := false this will be used as default value for LOCAL_DEX_PREOPT 398endif 399 400ifneq ($(USE_FIREOS_DEFAULT_DEXPREOPT),) 401 # shared settings for all FireOS dexpreopt modes 402 ifeq ($(filter-out userdata cache,$(USE_FIREOS_DEFAULT_DEXPREOPT)),) if $(USE_FIREOS_DEFAULT_DEXPREOPT) contain userdata or cache 403 WITH_DEXPREOPT := true 404 # Use this file to indicate that this is a fresh flash. 405 FACTORY_PREOPT_FLAG_FILE := FACTORY_PREOPT 406 # Don't precompile files matching these patterns in 407 # LOCAL_MODULE_PATH. 408 # Note: do not use := here - this must be expanded at use 409 # in order for PRODUCT_OUT to expand correctly. 410 NEVER_DEXPREOPT_DIRS = $(PRODUCT_OUT)/mw_test_apps/% 411 # We should dexpreopt prebuilts unless explicitly overridden 412 DONT_DEXPREOPT_PREBUILTS ?= false 413 endif # ifeq ($(filter-out true userdata cache,$(USE_FIREOS_DEFAULT_DEXPREOPT)),) 414 415 ifeq ($(filter-out userdata,$(USE_FIREOS_DEFAULT_DEXPREOPT)),) if $(USE_FIREOS_DEFAULT_DEXPREOPT) only contain userdata 416 # Install pre-compiled prebuilts to userdata. 417 DEXPREOPT_PREBUILTS_INSTALL := userdata 418 # Unsetting this should compile out run-time entry points for 419 # dalvik-cache in cache. 420 TARGET_DEXOPT_CACHEFS_SPACE_RESERVE := 421 else # ! ifeq ($(filter-out userdata,$(USE_FIREOS_DEFAULT_DEXPREOPT)),) 422 ifeq ($(USE_FIREOS_DEFAULT_DEXPREOPT),cache) if $(USE_FIREOS_DEFAULT_DEXPREOPT) only contain cache 423 # Install pre-compiled prebuilts to cache. 424 DEXPREOPT_PREBUILTS_INSTALL := cache 425 # Space reserved in the cache partition for system OTA use in kilobytes. 426 # Dexopt should leave at least this much space free. 427 TARGET_DEXOPT_CACHEFS_SPACE_RESERVE ?= 256000 428 endif # ifeq ($(USE_FIREOS_DEFAULT_DEXPREOPT),cache) 429 endif # ifeq ($(filter-out userdata,$(USE_FIREOS_DEFAULT_DEXPREOPT)),) 430endif # ifneq ($(USE_FIREOS_DEFAULT_DEXPREOPT),)131# If we don't already have an explicit LOCAL_DEX_PREOPT, set the 132# default from DEXPREOPT_PREBUILTS_INSTALL, if set. 133ifeq ($(LOCAL_DEX_PREOPT),) 134ifneq ($(DEXPREOPT_PREBUILTS_INSTALL),) 135LOCAL_DEX_PREOPT := $(DEXPREOPT_PREBUILTS_INSTALL) 136endif 137endif1354define build-userdataimage-target 1355 $(call pretty,"Target userdata fs image: $(INSTALLED_USERDATAIMAGE_TARGET)") 1356 @mkdir -p $(TARGET_OUT_DATA) 1358 $(if $(DEXPREOPT_PREBUILTS_INSTALL),\ 1359 $(if $(filter-out cache userdata,$(DEXPREOPT_PREBUILTS_INSTALL)),,\ 1360 $(hide) mkdir -p $(TARGET_OUT_DATA)/dalvik-cache/$(TARGET_ARCH) && \ 1361 touch $(TARGET_OUT_DATA)/dalvik-cache/$(TARGET_ARCH)/$(FACTORY_PREOPT_FLAG_FILE) ; \ 1362 $(if $(TARGET_2ND_ARCH),\ 1363 mkdir -p $(TARGET_OUT_DATA)/dalvik-cache/$(TARGET_2ND_ARCH) && \ 1364 touch $(TARGET_OUT_DATA)/dalvik-cache/$(TARGET_2ND_ARCH)/$(FACTORY_PREOPT_FLAG_FILE) \ 1365 ) \ 1366 ) \ 1367 ) ........................ 1380endefLOCAL_DEX_PREOPT initialize
115# Disable dex-preopt of prebuilts to save space, if requested. 116ifeq ($(DONT_DEXPREOPT_PREBUILTS),true) 117LOCAL_DEX_PREOPT := false 118endif 119 120ifneq ($(LOCAL_MODULE_PATH),) 121ifneq ($(NEVER_DEXPREOPT_DIRS),) 122# Test apps that are not pre-installed on the device are pointless to 123# dexpreopt. There may be more cases that should be excluded, so use 124# a general-purpose blacklist. 125ifeq ($(filter-out $(NEVER_DEXPREOPT_DIRS),$(LOCAL_MODULE_PATH)),) if the module path is in the exclusive app list, don't do preopt. 126LOCAL_DEX_PREOPT := false 127endif 128endif 129endif 130 131# If we don't already have an explicit LOCAL_DEX_PREOPT, set the 132# default from DEXPREOPT_PREBUILTS_INSTALL, if set. 133ifeq ($(LOCAL_DEX_PREOPT),) 134ifneq ($(DEXPREOPT_PREBUILTS_INSTALL),) 135LOCAL_DEX_PREOPT := $(DEXPREOPT_PREBUILTS_INSTALL) 136endif 137endif 138 139# Don't use cache space for apps that are installed on userdata if the 140# default will generally write to cache. 141ifneq ($(LOCAL_MODULE_PATH),) 142ifeq ($(LOCAL_DEX_PREOPT)$(filter-out $(TARGET_OUT_DATA)/%,$(LOCAL_MODULE_PATH)), cache) 143LOCAL_DEX_PREOPT := userdata 144endif 145endif207####################################### 208# defines built_odex along with rule to install odex 209include $(BUILD_SYSTEM)/dex_preopt_odex_install.mk 210#######################################284ifeq ($(words $(PRODUCT_RUNTIMES)),1) 285 # If we only have one runtime, we can strip classes.dex by default during dex_preopt 286 DEX_PREOPT_DEFAULT := true 287else 288 # If we have more than one, we leave the classes.dex alone for post-boot analysis 289 DEX_PREOPT_DEFAULT := nostripping 290endif
In dex_preopt_odex_install.mk5# Setting LOCAL_DEX_PREOPT based on WITH_DEXPREOPT, LOCAL_DEX_PREOPT, etc 6LOCAL_DEX_PREOPT := $(strip $(LOCAL_DEX_PREOPT)) 7ifneq (true,$(WITH_DEXPREOPT)) not do dexopt by default 8 LOCAL_DEX_PREOPT := 9else # WITH_DEXPREOPT=true 10 ifeq (,$(TARGET_BUILD_APPS)) # TARGET_BUILD_APPS empty 11 ifndef LOCAL_DEX_PREOPT # LOCAL_DEX_PREOPT undefined 12 ifneq ($(filter $(TARGET_OUT)/%,$(my_module_path)),) # Installed to system.img. 13 ifeq (,$(LOCAL_APK_LIBRARIES)) # LOCAL_APK_LIBRARIES empty 14 # If we have product-specific config for this module? 15 ifeq (disable,$(DEXPREOPT.$(TARGET_PRODUCT).$(LOCAL_MODULE).CONFIG)) 16 LOCAL_DEX_PREOPT := false 17 else 18 LOCAL_DEX_PREOPT := $(DEX_PREOPT_DEFAULT) 19 endif 20 else # LOCAL_APK_LIBRARIES not empty 21 LOCAL_DEX_PREOPT := nostripping 22 endif # LOCAL_APK_LIBRARIES not empty 23 endif # Installed to system.img. 24 endif # LOCAL_DEX_PREOPT undefined 25 endif # TARGET_BUILD_APPS empty 26endif # WITH_DEXPREOPT=true 27ifeq (false,$(LOCAL_DEX_PREOPT)) 28 LOCAL_DEX_PREOPT := 29endif 30ifdef LOCAL_UNINSTALLABLE_MODULE 31LOCAL_DEX_PREOPT := 32endif 33ifeq (,$(strip $(built_dex)$(my_prebuilt_src_file))) # contains no java code 34LOCAL_DEX_PREOPT := 35endif 36# if module oat file requested in data, disable LOCAL_DEX_PREOPT, will default location to dalvik-cache 37ifneq (,$(filter $(LOCAL_MODULE),$(PRODUCT_DEX_PREOPT_PACKAGES_IN_DATA))) 38LOCAL_DEX_PREOPT := 39endif 40# if WITH_DEXPREOPT_BOOT_IMG_ONLY=true and module is not in boot class path skip 41ifeq (true,$(WITH_DEXPREOPT_BOOT_IMG_ONLY)) 42ifeq ($(filter $(DEXPREOPT_BOOT_JARS_MODULES),$(LOCAL_MODULE)),) 43LOCAL_DEX_PREOPT := 44endif 45endif50ifdef LOCAL_DEX_PREOPT 51dexpreopt_boot_jar_module := $(filter $(DEXPREOPT_BOOT_JARS_MODULES),$(LOCAL_MODULE)) 52ifdef dexpreopt_boot_jar_module 53ifeq ($(DALVIK_VM_LIB),libdvm.so) 54built_odex := $(basename $(LOCAL_BUILT_MODULE)).odex 55installed_odex := $(basename $(LOCAL_INSTALLED_MODULE)).odex 56built_installed_odex := $(built_odex):$(installed_odex) 57else # libdvm.so 58# For libart, the boot jars' odex files are replaced by $(DEFAULT_DEX_PREOPT_INSTALLED_IMAGE). 59# We use this installed_odex trick to get boot.art installed. 60installed_odex := $(DEFAULT_DEX_PREOPT_INSTALLED_IMAGE) 61# Append the odex for the 2nd arch if we have one. 62installed_odex += $($(TARGET_2ND_ARCH_VAR_PREFIX)DEFAULT_DEX_PREOPT_INSTALLED_IMAGE) 63endif # libdvm.so 64else # boot jar 65ifeq ($(DALVIK_VM_LIB),libdvm.so) 66built_odex := $(basename $(LOCAL_BUILT_MODULE)).odex 67installed_odex := $(basename $(LOCAL_INSTALLED_MODULE)).odex 68built_installed_odex := $(built_odex):$(installed_odex) 69 70$(built_odex) : $(DEXPREOPT_ONE_FILE_DEPENDENCY_BUILT_BOOT_PREOPT) \ 71 $(DEXPREOPT_ONE_FILE_DEPENDENCY_TOOLS) 72else # libart 74LOCAL_DEX2OAT_TARGET_ARCH := $(DEX2OAT_TARGET_ARCH) 75$(TARGET_2ND_ARCH_VAR_PREFIX)LOCAL_DEX2OAT_TARGET_ARCH := $($(TARGET_2ND_ARCH_VAR_PREFIX)DEX2OAT_TARGET_ARCH) 141ifeq ($(LOCAL_DEX_PREOPT),cache) 142dexpreopt_install_root := $(TARGET_OUT_CACHE)/dalvik-cache/ 143else ifeq ($(LOCAL_DEX_PREOPT),userdata) 144dexpreopt_install_root := $(TARGET_OUT_DATA)/dalvik-cache/ 145else 146dexpreopt_install_root := $(dir $(LOCAL_INSTALLED_MODULE)) 147endif 148 149# Use pattern rule - we may have multiple installed odex files. 150# Ugly syntax - See the definition get-odex-file-path. 151$(installed_odex) : $(dexpreopt_install_root)%$(notdir $(word 1,$(installed_odex))) \ 152 : $(dir $(LOCAL_BUILT_MODULE))%$(notdir $(word 1,$(built_odex))) \ 153 | $(ACP) 154 $(call print-install,$@) #fosmod_build_extensions oneline 155 $(copy-file-to-target) 156endif 159# Add the installed_odex to the list of installed files for this module. 160ALL_MODULES.$(my_register_name).INSTALLED += $(installed_odex) 161ALL_MODULES.$(my_register_name).BUILT_INSTALLED += $(built_installed_odex) 162 163# Make sure to install the .odex when you run "make <module_name>" 164$(my_register_name): $(installed_odex) 165 166endif # LOCAL_DEX_PREOPT220ifdef LOCAL_DEX_PREOPT 222# dexpreopt to cache and userdata should not strip classes.dex 223ifneq ($(filter-out nostripping cache userdata,$(LOCAL_DEX_PREOPT)),) 225 $(call dexpreopt-remove-classes.dex,$@) 226endif 227endif 228 $(align-package) 229 230############################### 231## Rule to build the odex file 232ifdef LOCAL_DEX_PREOPT 233$(built_odex) : $(my_prebuilt_src_file) 234 $(call dexpreopt-one-file,$<,$@) 235endif
odex是从APK中提取出来的可运行文件,即将APK中的class.dex文件通过
dex优化过程将其优化生成odex文件单独存放。如果没有odex,系统需要在开机过程中从APK内提取dex再运行;如果在build过程中预先提取,可加快系统启动速度、节省开机时间。
一般情况下:
User 版本会预先提取有source code的APK的odex文件,因为有source code的APK在Android.mk中都会通过include $(BUILD_PACKAGE)来编译,会调用到package.mk来提取odex
但User版本不会预先提取通过prebuilt方式预置的APK的odex文件,因为采用prebuilt方式预置APK是只有APK文件而没有source code时,在Android.mk中通过 include $(BUILD_PREBUILT)预置APK,代码中原本的prebuilt.mk中不会提取odex。
方法:
实现prebuilt APK提取odex的修改方法如下:修改build/core/prebuilt.mk
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)
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)
endif
ifdef LOCAL_DEX_PREOPT
built_odex := $(basename $(built_module)).odex
$(built_odex): $(built_module)
endif
else
... ...
注意:
(1)user build默认开启dexopt功能,eng build关闭,所以只是build user版本会提取APK的odex文件。
(2)请务必不要忘记把预置的module添加到build/target/product/common.mk(或者[proj].mk)中的PRODUCT_PACKAGES里面。
(3)只有prebuilt预置APK时会生效,放置在vendor下拷贝的方式来预置APK是不会生效的。