Android学习笔记之编译系统(五)apk编译流程

apk项目是如何编译的?

总结:

我们可以通过mm showcommands命令查看编译过程。今天下载了小米的Notes,便签,没有Android.mk文件,自己加上了Androd.mk,将这个项目放在自己的电脑工程下编译。总结了一下编译过程,不当之处请指正。参考柯元旦android内核剖析。

接下来我们就按顺序看看apk编译过程中的流程。

1、首先编译项目下的资源文件,生成R.java文件。因为资源文件相对独立,不会跟java文件存在依赖,相反java文件要以来资源文件,因为我们在java文件中通过R.string.xx来引用具体某个资源。编译res资源文件,主要是aap进行编译。命令使用:

-J :指定R.java的输出目录

-M:指定AndroidManifest.xml的位置

-P:指定public_resources.xml的输出目录,这个文件记述了apk资源中属性的相关描述

-S:指定res目录的路径

-I:指定apk项目可能引用的其他资源,比如framework层下的资源。

比如短彩信中会引用framework下的资源

  1. chips_dir := http://www.cnblogs.com/../frameworks/ex/chips/res 
  2. res_dirs := $(chips_dir) res 
  3. LOCAL_RESOURCE_DIR := $(addprefix $(LOCAL_PATH)/, $(res_dirs)) 
chips_dir := http://www.cnblogs.com/../frameworks/ex/chips/res
res_dirs := $(chips_dir) res
LOCAL_RESOURCE_DIR := $(addprefix $(LOCAL_PATH)/, $(res_dirs))

 

  1. aapt package  -z -m  -J out/target/common/obj/APPS/MiuiNotes_intermediates/src -M packages/apps/Notes/AndroidManifest.xml -P out/target/common/obj/APPS/MiuiNotes_intermediates/public_resources.xml -S packages/apps/Notes/res 
aapt package  -z -m  -J out/target/common/obj/APPS/MiuiNotes_intermediates/src -M packages/apps/Notes/AndroidManifest.xml -P out/target/common/obj/APPS/MiuiNotes_intermediates/public_resources.xml -S packages/apps/Notes/res

我们可以看到 -J指定了R.java的输出目录 -M,指定了AndroidManifest.xml文件的路径 -P指定了public_resource.xml的位置 -S:指定了res的编译目录。

执行完aapt命令,那么就会在相应的输出目录中存在一个R.java文件了。

2、编译aidl文件。

我们在上篇文章中展示了如何在Android.mk文件中添加aidl文件。要编译aidl文件需要aidl命令,aidl 参数 输入 输出。

3、包含java静态库,也就是jar包。

有的模块需要第三方支持,有时候第三方为了保护代码,会提供一个jar,没有源文件。编译系统定义了这部分规则。

  1. for f in  out/target/common/obj/JAVA_LIBRARIES/android-support-v4_intermediates/javalib.jar; doif [ ! -f $f ]; then echo Missing file $f; exit 1; fi; unzip -qo $f -d /out/target/common/obj/APPS/MiuiNotes_intermediates/classes; (cd /out/target/common/obj/APPS/MiuiNotes_intermediates/classes && rm -rf META-INF); done 
for f in  out/target/common/obj/JAVA_LIBRARIES/android-support-v4_intermediates/javalib.jar; do if [ ! -f $f ]; then echo Missing file $f; exit 1; fi; unzip -qo $f -d /out/target/common/obj/APPS/MiuiNotes_intermediates/classes; (cd /out/target/common/obj/APPS/MiuiNotes_intermediates/classes && rm -rf META-INF); done

jar文件会被解压缩,然后拷贝解压缩后的class文件到out下对应app的src目录下。

4、编译java源文件,生成jar包。

首先将找到所有的*.java文件,将他们编译生成class文件。

-bootclasspath:指定java运行库core.jar。core.jar中包含着Dalvik虚拟机运行时所需的java库。

-classpath:指定静态库,例如core.jar、framework.jar、ext.jar等。

-d:指明class的输出路径

  1. javac -J-Xmx512M -target 1.5 -Xmaxerrs 9999999 -encoding UTF-8 -g  -bootclasspath out/target/common/obj/JAVA_LIBRARIES/core_intermediates/classes.jar <SPAN style="FONT-FAMILY: Arial, Helvetica, sans-serif">-classpath /out/target/common/obj/JAVA_LIBRARIES/core_intermediates/classes.jar:/out/target/common/obj/JAVA_LIBRARIES/core-junit_intermediates/classes.jar:/out/target/common/obj/JAVA_LIBRARIES/ext_intermediates/classes.jar:/out/target/common/obj/JAVA_LIBRARIES/framework_intermediates/classes.jar:/out/target/common/obj/JAVA_LIBRARIES/framework2_intermediates/classes.jar:/out/target/common/obj/JAVA_LIBRARIES/android-support-v4_intermediates/javalib.jar  -extdirs "" -d /out/target/common/obj/APPS/MiuiNotes_intermediates/classes </SPAN> 
javac -J-Xmx512M -target 1.5 -Xmaxerrs 9999999 -encoding UTF-8 -g  -bootclasspath out/target/common/obj/JAVA_LIBRARIES/core_intermediates/classes.jar -classpath /out/target/common/obj/JAVA_LIBRARIES/core_intermediates/classes.jar:/out/target/common/obj/JAVA_LIBRARIES/core-junit_intermediates/classes.jar:/out/target/common/obj/JAVA_LIBRARIES/ext_intermediates/classes.jar:/out/target/common/obj/JAVA_LIBRARIES/framework_intermediates/classes.jar:/out/target/common/obj/JAVA_LIBRARIES/framework2_intermediates/classes.jar:/out/target/common/obj/JAVA_LIBRARIES/android-support-v4_intermediates/javalib.jar  -extdirs "" -d /out/target/common/obj/APPS/MiuiNotes_intermediates/classes 

然后将这些所有的class文件打包成class.jar包,这些class文件应该就包含上一步jar包解压缩后产生的class文件。

  1. jar -cf /out/target/common/obj/APPS/MiuiNotes_intermediates/classes-full-debug.jar  -C /out/target/common/obj/APPS/MiuiNotes_intermediates/classes . 
jar -cf /out/target/common/obj/APPS/MiuiNotes_intermediates/classes-full-debug.jar  -C /out/target/common/obj/APPS/MiuiNotes_intermediates/classes .

-cf:c代表创建一个新的jar包,f:指定jar包的名称。-C:指定jar包包含的文件,此处就是刚才生成的所有的class文件。

生成了class-full-debug.jar。

然后执行

  1. acp -fp /out/target/common/obj/APPS/MiuiNotes_intermediates/classes-full-debug.jar /out/target/common/obj/APPS/MiuiNotes_intermediates/classes-jarjar.jar 
acp -fp /out/target/common/obj/APPS/MiuiNotes_intermediates/classes-full-debug.jar /out/target/common/obj/APPS/MiuiNotes_intermediates/classes-jarjar.jar
  1. acp -fp /out/target/common/obj/APPS/MiuiNotes_intermediates/classes-jarjar.jar /out/target/common/obj/APPS/MiuiNotes_intermediates/emma_out/lib/classes-jarjar.jar 
acp -fp /out/target/common/obj/APPS/MiuiNotes_intermediates/classes-jarjar.jar /out/target/common/obj/APPS/MiuiNotes_intermediates/emma_out/lib/classes-jarjar.jar

 

  1. acp -fp /out/target/common/obj/APPS/MiuiNotes_intermediates/emma_out/lib/classes-jarjar.jar /out/target/common/obj/APPS/MiuiNotes_intermediates/classes.jar 
acp -fp /out/target/common/obj/APPS/MiuiNotes_intermediates/emma_out/lib/classes-jarjar.jar /out/target/common/obj/APPS/MiuiNotes_intermediates/classes.jar
  1. acp -fp /out/target/common/obj/APPS/MiuiNotes_intermediates/classes.jar /out/target/common/obj/APPS/MiuiNotes_intermediates/noproguard.classes.jar 
acp -fp /out/target/common/obj/APPS/MiuiNotes_intermediates/classes.jar /out/target/common/obj/APPS/MiuiNotes_intermediates/noproguard.classes.jar

复制刚才产生的classes-full-debug.jar ,生成四个文件,classes-jarjar.jar、classed-jarjar.jar、classes.jar、noproguard.classes.jar

5、将jar包转换为dex文件。

在android系统中构建了一个java虚拟机,这个虚拟机需要的是dex文件。在编译系统中我们可以使用dx工具,将jar文件转换为dex文件。

--dex:产生一个dex格式的文件

--output:指定输出路径

最后指定要转换为dex的jar文件。

  1. /out/host/linux-x86/bin/dx -JXms16M -JXmx2048M --dex --output=/out/target/common/obj/APPS/MiuiNotes_intermediates/noproguard.classes-with-local.dex     /out/target/common/obj/APPS/MiuiNotes_intermediates/noproguard.classes.jar 
/out/host/linux-x86/bin/dx -JXms16M -JXmx2048M --dex --output=/out/target/common/obj/APPS/MiuiNotes_intermediates/noproguard.classes-with-local.dex     /out/target/common/obj/APPS/MiuiNotes_intermediates/noproguard.classes.jar

生成了noproguard.classes-with-local.dex文件,接下来

  1. acp -fp /out/target/common/obj/APPS/MiuiNotes_intermediates/noproguard.classes-with-local.dex /out/target/common/obj/APPS/MiuiNotes_intermediates/noproguard.classes.dex 
acp -fp /out/target/common/obj/APPS/MiuiNotes_intermediates/noproguard.classes-with-local.dex /out/target/common/obj/APPS/MiuiNotes_intermediates/noproguard.classes.dex

复制产生一个noproguard.classes.dex文件。

6、编译资源文件生成apk包

apk包,本质上是个zip压缩文件包。将它解压缩我们可以看到这个包中文件列表如下:

  1. inflating: res/layout/activity_main.xml   
  2.   inflating: res/menu/main.xml        
  3.   inflating: AndroidManifest.xml      
  4. extracting: resources.arsc           
  5. extracting: res/drawable-hdpi/ic_launcher.png   
  6. extracting: res/drawable-mdpi/ic_launcher.png   
  7. extracting: res/drawable-xhdpi/ic_launcher.png   
  8. extracting: res/drawable-xxhdpi/ic_launcher.png   
  9.   inflating: classes.dex              
  10.   inflating: META-INF/MANIFEST.MF     
  11.   inflating: META-INF/CERT.SF         
  12.   inflating: META-INF/CERT.RSA 
inflating: res/layout/activity_main.xml  
  inflating: res/menu/main.xml       
  inflating: AndroidManifest.xml     
 extracting: resources.arsc          
 extracting: res/drawable-hdpi/ic_launcher.png  
 extracting: res/drawable-mdpi/ic_launcher.png  
 extracting: res/drawable-xhdpi/ic_launcher.png  
 extracting: res/drawable-xxhdpi/ic_launcher.png  
  inflating: classes.dex             
  inflating: META-INF/MANIFEST.MF    
  inflating: META-INF/CERT.SF        
  inflating: META-INF/CERT.RSA

包含resource.arsc:包含了所有资源文件的id值和路径的映射关系

res目录:原封不动的复制了开发时的res目录

class.dex:java源文件达成jar包,然后dx工具将jar包转化为jar

AndroidManifest.xml:源文件的二进制文件。

编译apk时,aapt首先将资源文件等除class.dex文件之外的所有文件打包成apk文件,然后再将classes.dex文件添加到apk文件中。

aapt工具参与了编译资源文件,参与了将源文件打包成apk。编译资源时使用命令参数 -m -J,-m的含义是告诉aapt使用-J后面的路径为输出路径。在将资源文件jar包压缩成apk时,使用-F参数,后面指定输出路径。-u代表如果目标apk存在,更新包中的内容。

  1. aapt package -u  -z -c en_US,en_US,cs_CZ,da_DK,de_AT,de_CH,de_DE,de_LI,el_GR,en_AU,en_CA,en_GB,en_NZ,en_SG,es_ES,fr_CA,fr_CH,fr_BE,fr_FR,it_CH,it_IT,ja_JP,ko_KR,nb_NO,nl_BE,nl_NL,pl_PL,pt_PT,ru_RU,sv_SE,tr_TR,zh_CN,zh_HK,zh_TW,am_ET,hi_IN,ug_CN,en_US,fr_FR,it_IT,es_ES,de_DE,nl_NL,cs_CZ,pl_PL,ja_JP,zh_TW,zh_CN,ru_RU,ko_KR,nb_NO,es_US,da_DK,el_GR,tr_TR,pt_PT,pt_BR,rm_CH,sv_SE,bg_BG,ca_ES,en_GB,fi_FI,hi_IN,hr_HR,hu_HU,in_ID,iw_IL,lt_LT,lv_LV,ro_RO,sk_SK,sl_SI,sr_RS,uk_UA,vi_VN,tl_PH,ar_EG,fa_IR,th_TH,sw_TZ,ms_MY,af_ZA,zu_ZA,am_ET,hi_IN,ug_CN,mdpi,nodpi  -M packages/apps/Notes/AndroidManifest.xml -S packages/apps/Notes/res  -I /out/target/common/obj/APPS/framework-res_intermediates/package-export.apk --min-sdk-version 16 --target-sdk-version 16 --product default --version-code 16 --version-name 4.1.2-eng.hlwang.20130310.122659   -F /out/target/product/generic/obj/APPS/MiuiNotes_intermediates/package.apk 
aapt package -u  -z -c en_US,en_US,cs_CZ,da_DK,de_AT,de_CH,de_DE,de_LI,el_GR,en_AU,en_CA,en_GB,en_NZ,en_SG,es_ES,fr_CA,fr_CH,fr_BE,fr_FR,it_CH,it_IT,ja_JP,ko_KR,nb_NO,nl_BE,nl_NL,pl_PL,pt_PT,ru_RU,sv_SE,tr_TR,zh_CN,zh_HK,zh_TW,am_ET,hi_IN,ug_CN,en_US,fr_FR,it_IT,es_ES,de_DE,nl_NL,cs_CZ,pl_PL,ja_JP,zh_TW,zh_CN,ru_RU,ko_KR,nb_NO,es_US,da_DK,el_GR,tr_TR,pt_PT,pt_BR,rm_CH,sv_SE,bg_BG,ca_ES,en_GB,fi_FI,hi_IN,hr_HR,hu_HU,in_ID,iw_IL,lt_LT,lv_LV,ro_RO,sk_SK,sl_SI,sr_RS,uk_UA,vi_VN,tl_PH,ar_EG,fa_IR,th_TH,sw_TZ,ms_MY,af_ZA,zu_ZA,am_ET,hi_IN,ug_CN,mdpi,nodpi  -M packages/apps/Notes/AndroidManifest.xml -S packages/apps/Notes/res  -I /out/target/common/obj/APPS/framework-res_intermediates/package-export.apk --min-sdk-version 16 --target-sdk-version 16 --product default --version-code 16 --version-name 4.1.2-eng.hlwang.20130310.122659   -F /out/target/product/generic/obj/APPS/MiuiNotes_intermediates/package.apk

7、将dex文件添加到apk包中。

由于apk本身就是个zip压缩包,因此将dex文件添加进去的,很容易。

  1. _adtp_classes_dex=/out/target/common/obj/APPS/MiuiNotes_intermediates/classes.dex; cp /out/target/common/obj/APPS/MiuiNotes_intermediates/noproguard.classes.dex $_adtp_classes_dex && /out/host/linux-x86/bin/aapt add -k /out/target/product/generic/obj/APPS/MiuiNotes_intermediates/package.apk $_adtp_classes_dex && rm -f $_adtp_classes_dex 
_adtp_classes_dex=/out/target/common/obj/APPS/MiuiNotes_intermediates/classes.dex; cp /out/target/common/obj/APPS/MiuiNotes_intermediates/noproguard.classes.dex $_adtp_classes_dex && /out/host/linux-x86/bin/aapt add -k /out/target/product/generic/obj/APPS/MiuiNotes_intermediates/package.apk $_adtp_classes_dex && rm -f $_adtp_classes_dex

首先定义class.dex文件,然后执行cp,拷贝刚才生成的noproguard.class.dex文件到class.dex中,然后调用aapt add -k命令,将class.dex添加到package.apk中,最后删除class.dex文件。

这样在out下的相应应用的目录中就产生了一个package.apk文件了。并且这个package.apk文件包含了一个完整apk所应该有的所有内容。

有时候我们的apk中需要JNI的支持,那么我们就需要将JNI所实现的库包含到apk中。我们通过在Android.mk文件中对变量LOCAL_JNI_SHARED_LIBRARIES进行赋值。在编译apk时,我们调用了 include $(BUILD_PACKAGE),这个变量在编译系统中会加载package.mk,在这个文件中,规则了加载LOCAL_JNI_SHARED_LIBARIES变量所对应的文件。

  1. jni_shared_libraries := \ 
  2.     $(addprefix $($(my_prefix)OUT_INTERMEDIATE_LIBRARIES)/, \ 
  3.       $(addsuffix $(so_suffix), \ 
  4.         $(LOCAL_JNI_SHARED_LIBRARIES))) 
jni_shared_libraries := \
    $(addprefix $($(my_prefix)OUT_INTERMEDIATE_LIBRARIES)/, \
      $(addsuffix $(so_suffix), \
        $(LOCAL_JNI_SHARED_LIBRARIES)))

这段代码会给要加载进去的库写上前缀路径,以及后缀.so。

然后在package.mk后面会判断这段代码是否为空,如果不为空,则将这个库文件拷贝到apk目录下的lib下。

java静态库在编译时不会包含到apk中,动态共享库会包含到apk中,详见:http://blog.csdn.net/hailushijie/article/details/8648665

  1. ifneq ($(jni_shared_libraries),) 
  2.         $(add-jni-shared-libs-to-package
  3. endif 
ifneq ($(jni_shared_libraries),)
        $(add-jni-shared-libs-to-package)
endif

关于add-jni-shared-libs-to-package变量的定义实在编译系统初始化时在definations.mk中定义的。

  1. define add-jni-shared-libs-to-package 
  2. $(hide) rm -rf $(dir $@)lib 
  3. $(hide) mkdir -p $(dir $@)lib/$(PRIVATE_JNI_SHARED_LIBRARIES_ABI) 
  4. $(hide) cp $(PRIVATE_JNI_SHARED_LIBRARIES) $(dir $@)lib/$(PRIVATE_JNI_SHARED_LIBRARIES_ABI) 
  5. $(hide) (cd $(dir $@) && zip -r $(notdir $@) lib) 
  6. $(hide) rm -rf $(dir $@)lib 
  7. endef 
define add-jni-shared-libs-to-package
$(hide) rm -rf $(dir $@)lib
$(hide) mkdir -p $(dir $@)lib/$(PRIVATE_JNI_SHARED_LIBRARIES_ABI)
$(hide) cp $(PRIVATE_JNI_SHARED_LIBRARIES) $(dir $@)lib/$(PRIVATE_JNI_SHARED_LIBRARIES_ABI)
$(hide) (cd $(dir $@) && zip -r $(notdir $@) lib)
$(hide) rm -rf $(dir $@)lib
endef

以源码的方式包含库文件,package/inputmethods/PinyinIME

  1. include $(BUILD_PACKAGE) 
  2.  
  3. MY_PATH := $(LOCAL_PATH) 
  4.  
  5. include $(MY_PATH)/jni/Android.mk 
  6. include $(MY_PATH)/lib/Android.mk 
include $(BUILD_PACKAGE)

MY_PATH := $(LOCAL_PATH)

include $(MY_PATH)/jni/Android.mk
include $(MY_PATH)/lib/Android.mk

8、对apk文件进行签名

  1. mv /out/target/product/generic/obj/APPS/MiuiNotes_intermediates/package.apk /out/target/product/generic/obj/APPS/MiuiNotes_intermediates/package.apk.unsigned 
  2. java -jar /out/host/linux-x86/framework/signapk.jar build/target/product/security/testkey.x509.pem build/target/product/security/testkey.pk8 /out/target/product/generic/obj/APPS/MiuiNotes_intermediates/package.apk.unsigned /out/target/product/generic/obj/APPS/MiuiNotes_intermediates/package.apk.signed 
  3. mv /out/target/product/generic/obj/APPS/MiuiNotes_intermediates/package.apk.signed /out/target/product/generic/obj/APPS/MiuiNotes_intermediates/package.apk 
mv /out/target/product/generic/obj/APPS/MiuiNotes_intermediates/package.apk /out/target/product/generic/obj/APPS/MiuiNotes_intermediates/package.apk.unsigned
java -jar /out/host/linux-x86/framework/signapk.jar build/target/product/security/testkey.x509.pem build/target/product/security/testkey.pk8 /out/target/product/generic/obj/APPS/MiuiNotes_intermediates/package.apk.unsigned /out/target/product/generic/obj/APPS/MiuiNotes_intermediates/package.apk.signed
mv /out/target/product/generic/obj/APPS/MiuiNotes_intermediates/package.apk.signed /out/target/product/generic/obj/APPS/MiuiNotes_intermediates/package.apk

首先将上一步中的package.apk更名为package.apk.unsigned,然后调用signapk.jar、testkey.x509.pem,testkey.pk8给更名的package.apk.unsigned签名后生成package.apk.signed。

最后在把package.apk.signed更名为package.apk。

9、使用zipalign优化apk内部存储。

为了提高apk程序的加载速度,使用zipalign对apk进行边界对齐。

  1. mv /out/target/product/generic/obj/APPS/MiuiNotes_intermediates/package.apk.signed /out/target/product/generic/obj/APPS/MiuiNotes_intermediates/package.apk 
  2. mv /out/target/product/generic/obj/APPS/MiuiNotes_intermediates/package.apk /out/target/product/generic/obj/APPS/MiuiNotes_intermediates/package.apk.unaligned 
  3. /out/host/linux-x86/bin/zipalign -f 4 /out/target/product/generic/obj/APPS/MiuiNotes_intermediates/package.apk.unaligned /out/target/product/generic/obj/APPS/MiuiNotes_intermediates/package.apk.aligned 
  4. mv /out/target/product/generic/obj/APPS/MiuiNotes_intermediates/package.apk.aligned /out/target/product/generic/obj/APPS/MiuiNotes_intermediates/package.apk 
mv /out/target/product/generic/obj/APPS/MiuiNotes_intermediates/package.apk.signed /out/target/product/generic/obj/APPS/MiuiNotes_intermediates/package.apk
mv /out/target/product/generic/obj/APPS/MiuiNotes_intermediates/package.apk /out/target/product/generic/obj/APPS/MiuiNotes_intermediates/package.apk.unaligned
/out/host/linux-x86/bin/zipalign -f 4 /out/target/product/generic/obj/APPS/MiuiNotes_intermediates/package.apk.unaligned /out/target/product/generic/obj/APPS/MiuiNotes_intermediates/package.apk.aligned
mv /out/target/product/generic/obj/APPS/MiuiNotes_intermediates/package.apk.aligned /out/target/product/generic/obj/APPS/MiuiNotes_intermediates/package.apk

过程和签名基本相似。

10、dex-preopt优化。

 

  1. dalvik/tools/dex-preopt --dexopt=host/linux-x86/bin/dexopt --build-dir=/out --product-dir=target/product/generic/dex_bootjars --boot-dir=system/framework --boot-jars=core:core-junit:bouncycastle:ext:framework:framework2:android.policy:services:apache-xml --uniprocessor target/product/generic/obj/APPS/MiuiNotes_intermediates/package.apk target/product/generic/obj/APPS/MiuiNotes_intermediates/package.odex 
dalvik/tools/dex-preopt --dexopt=host/linux-x86/bin/dexopt --build-dir=/out --product-dir=target/product/generic/dex_bootjars --boot-dir=system/framework --boot-jars=core:core-junit:bouncycastle:ext:framework:framework2:android.policy:services:apache-xml --uniprocessor target/product/generic/obj/APPS/MiuiNotes_intermediates/package.apk target/product/generic/obj/APPS/MiuiNotes_intermediates/package.odex

 

package.apk作为输入文件,将其中的dex文件输出到package.odex中。

将class.dex文件从package.apk中移除

 

  1. /out/host/linux-x86/bin/aapt remove /out/target/product/generic/obj/APPS/MiuiNotes_intermediates/package.apk classes.dex 
/out/host/linux-x86/bin/aapt remove /out/target/product/generic/obj/APPS/MiuiNotes_intermediates/package.apk classes.dex

这样package.apk中就不再含有class.dex文件了。

 

怎样设置才能不进行这一步

在我们执行Android.mk时,最后一步,call $BUILD_PACKAGE时,会检查WITH_DEXPREOPT的值是否为true,然后对LOCAL_DEX_PREOPT进行赋值。

 

  1. ifneq (true,$(WITH_DEXPREOPT)) 
  2. LOCAL_DEX_PREOPT := 
  3. else 
  4. ifeq (,$(TARGET_BUILD_APPS)) 
  5. ifneq (,$(LOCAL_SRC_FILES)) 
  6. ifndef LOCAL_DEX_PREOPT 
  7. LOCAL_DEX_PREOPT := true 
ifneq (true,$(WITH_DEXPREOPT))
LOCAL_DEX_PREOPT :=
else
ifeq (,$(TARGET_BUILD_APPS))
ifneq (,$(LOCAL_SRC_FILES))
ifndef LOCAL_DEX_PREOPT
LOCAL_DEX_PREOPT := true

然后在base_rules.mk中

 

 

  1. ifdef (true,$(LOCAL_DEX_PREOPT)) 
  2. installed_odex := $(basename $(LOCAL_INSTALLED_MODULE)).odex 
  3. built_odex := $(basename $(LOCAL_BUILT_MODULE)).odex 
  4. $(installed_odex) : $(built_odex) | $(ACP) 
  5.         @echo -e ${CL_CYN}"Install: $@"${CL_RST} 
  6.         $(copy-file-to-target) 
  7.  
  8. $(LOCAL_INSTALLED_MODULE) : $(installed_odex) 
  9. endif 
ifdef (true,$(LOCAL_DEX_PREOPT))
installed_odex := $(basename $(LOCAL_INSTALLED_MODULE)).odex
built_odex := $(basename $(LOCAL_BUILT_MODULE)).odex
$(installed_odex) : $(built_odex) | $(ACP)
        @echo -e ${CL_CYN}"Install: $@"${CL_RST}
        $(copy-file-to-target)

$(LOCAL_INSTALLED_MODULE) : $(installed_odex)
endif

这样apk在编译时就能进行dex-preopt优化了。

 

所以,我们可以更改WITH_DEXPREOPT的值为false,或者更改LOCAL_DEX_PREOPT的值。都ok。WITH_DEXPREOPT的值在BoardConfig.mk中定义,LOCAL_DEX_PREOPT的值在package.mk中定义。

网上有人说修改system.prop文件,增加

dalvik.vm.verify-bytecode = false不知道是否ok。 如果不进行这个步骤,那么我们的apk文件中将会包含所有的文件,包括class.dex,如果包括这步则apk内不含有class.dex文件,class.dex将会以应用名.odex文件存在。

11、odex文件

  1. dalvik/tools/dex-preopt --dexopt=host/linux-x86/bin/dexopt --build-dir=/out --product-dir=target/product/generic/dex_bootjars --boot-dir=system/framework --boot-jars=core:core-junit:bouncycastle:ext:framework:framework2:android.policy:services:apache-xml --uniprocessor target/product/generic/obj/APPS/MiuiNotes_intermediates/package.apk target/product/generic/obj/APPS/MiuiNotes_intermediates/package.odex 
dalvik/tools/dex-preopt --dexopt=host/linux-x86/bin/dexopt --build-dir=/out --product-dir=target/product/generic/dex_bootjars --boot-dir=system/framework --boot-jars=core:core-junit:bouncycastle:ext:framework:framework2:android.policy:services:apache-xml --uniprocessor target/product/generic/obj/APPS/MiuiNotes_intermediates/package.apk target/product/generic/obj/APPS/MiuiNotes_intermediates/package.odex

odex可能为了加速apk的解析吧。

最后生成了package.odex。

  1. acp -fp /out/target/product/generic/obj/APPS/MiuiNotes_intermediates/package.odex /out/target/product/generic/system/app/MiuiNotes.odex 
acp -fp /out/target/product/generic/obj/APPS/MiuiNotes_intermediates/package.odex /out/target/product/generic/system/app/MiuiNotes.odex

拷贝刚才生成的package.odex,生成MiuiNotes.odex。

12、拷贝package.apk生成目标apk

  1. acp -fp /out/target/product/generic/obj/APPS/MiuiNotes_intermediates/package.apk /out/target/product/generic/system/app/MiuiNotes.apk 
acp -fp /out/target/product/generic/obj/APPS/MiuiNotes_intermediates/package.apk /out/target/product/generic/system/app/MiuiNotes.apk

 

这样我们通过编译同时生成了MiuiNotes.apk以及MiuiNotes.odex文件。

我们的源文件class.dex包含在MiuiNotes.odex中,我们的MiuiNotes.apk中包括资源文件。

posted @ 2013-03-12 22:16  天地乐  阅读(1431)  评论(0)    收藏  举报