編譯過android源代碼的可能試驗過改動編譯類型。android的初始化編譯配置可參考Android——編譯系統初始化設置
一.TARGET_BUILD_VARIANT=user
當選擇的編譯類型為user的時候。能夠在/build/core/main.mk中看到(android 4.2):
# Turn on Dalvik preoptimization for user builds, but only if not # explicitly disabled and the build is running on Linux (since host # Dalvik isn't built for non-Linux hosts). ifneq (true,$(DISABLE_DEXPREOPT)) ifeq ($(user_variant),user) ifeq ($(HOST_OS),linux) WITH_DEXPREOPT := true endif endif endif
從上面的邏輯能夠看出來 DISABLE_DEXPREOPT 設置以及:
user_variant := $(filter user userdebug,$(TARGET_BUILD_VARIANT))
和HOST_OS 這三個變量決定WITH_DEXPREOPT
當編譯的時候,遍歷須要編譯的MODULE的時候,在/build/core/package.mk。至於為什么會買這個makefile來是由於MODULE中的android.mk 中include $(BUILD_PACKAGE)。這個是android的編譯體系了。
ifneq (true,$(WITH_DEXPREOPT)) LOCAL_DEX_PREOPT := else ifeq (,$(TARGET_BUILD_APPS)) ifneq (,$(LOCAL_SRC_FILES)) ifndef LOCAL_DEX_PREOPT LOCAL_DEX_PREOPT := true endif endif endif endif ifeq (false,$(LOCAL_DEX_PREOPT)) LOCAL_DEX_PREOPT := endif
從package.mk中的這部分邏輯能夠看出來。 TARGET_BUILD_APPS 置空 是在前面的文章中的lunch命令中設置的。代表全編譯!
並且LOCAL_SRC_FILES不能為空,意思就是有源代碼的
這個時候假設沒定義。那么變量LOCAL_DEX_PREOPT = true。
接着往下看:
ifdef LOCAL_DEX_PREOPT # Make sure the boot jars get dexpreopt-ed first $(LOCAL_BUILT_MODULE): $(DEXPREOPT_BOOT_ODEXS) | $(DEXPREOPT) $(DEXOPT) endif
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
這兩個邏輯的運行都在/build/core/dex_preopt.mk中
DEXPREOPT_BOOT_ODEXS := $(foreach b,$(DEXPREOPT_BOOT_JARS_MODULES),\ $(DEXPREOPT_BOOT_JAR_DIR_FULL_PATH)/$(b).odex)
工具在/build/core/config.mk中定義:
DEXOPT := $(HOST_OUT_EXECUTABLES)/dexopt$(HOST_EXECUTABLE_SUFFIX) DEXPREOPT := dalvik/tools/dex-preopt
在生成apk和jar的處理:
# $(1): the input .jar or .apk file # $(2): the output .odex file define dexpreopt-one-file $(hide) $(DEXPREOPT) --dexopt=$(DEXPREOPT_DEXOPT) --build-dir=$(DEXPREOPT_BUILD_DIR) \ --product-dir=$(DEXPREOPT_PRODUCT_DIR) --boot-dir=$(DEXPREOPT_BOOT_JAR_DIR) \ --boot-jars=$(DEXPREOPT_BOOT_JARS) $(DEXPREOPT_UNIPROCESSOR) \ $(patsubst $(DEXPREOPT_BUILD_DIR)/%,%,$(1)) \ $(patsubst $(DEXPREOPT_BUILD_DIR)/%,%,$(2)) endef
# $(1): the .jar or .apk to remove classes.dex define dexpreopt-remove-classes.dex $(hide) $(AAPT) remove $(1) classes.dex endef
來移除.dex
大體的編譯配置和流程介紹到這里,細節都在這么幾個文件中面,不多寫了!
二. .odex作用
上面說了生成*.odex,每個相應的jar和apk都能生成一個相應的.odex,同一時候去除了.dex。這樣單獨的jar 和apk 就不完整了,無法正常被android系統使用的! 僅僅有配合.odex使用。
系統制作會把.odex 和 apk 一起放到system/app 下,由系統來調度使用,假設想盜版apk,單獨copy出去.apk是不能用的。還必須反編譯相應的.odex為.dex,又一次打包進apk包。才干使用,而反編譯.odex 還須要用到這個這個apk有使用到的相關jar包。
而我們系統制作的framework.jar也是有framework.odex的。這樣能夠起到一定程度上的保護作用!至於網上各種反編譯odex 然后簽名的方法有非常多,不多做介紹。
撰寫不易,轉載請注明出處:http://blog.csdn.net/jscese/article/details/32702321