android打包流程

summary

build-process
  • 编译src文件,生成class文件
  • 将class文件编译成为dex文件
  • 编译资源文件(不包括assets,raw和so等文件),生成R文件
  • 将上述的两个以及一些依赖进行联合编译成为一个apk
  • 压平
  • 签名(debug,release)
  • debug:default
  • release:生成一个keystore文件

class->dex

class:基于栈
dex:基于寄存器

difference_between_class_dex
difference_between_class_dex

1、优化常量池;
2、基于寄存器更容易操作硬件内容,适合移动端

detail

build-process-detail

资源打包系统

二进制格式的XML文件占用空间更小。

这是由于所有XML元素的标签、属性名称、属性值和内容所涉及到的字符串都会被统一收集到一个字符串资源池中去,并且会去重。有了这个字符串资源池,原来使用字符串的地方就会被替换成一个索引到字符串资源池的整数值,从而可以减少文件的大小。

二进制格式的XML文件解析速度更快。

这是由于二进制格式的XML元素里面不再包含有字符串值,因此就避免了进行字符串解析,从而提高速度。

小结

  • 除了assets和res/raw资源被原装不动地打包进APK之外,其它的资源都会被编译或者处理;
  • 除了assets资源之外,其它的资源都会被赋予一个资源ID;
  • 打包工具负责编译和打包资源,编译完成之后,会生成一个resources.arsc文件和一个R.java,前者保存的是一个资源索引表,后者定义了各个资源ID常量。
  • 应用程序配置文件AndroidManifest.xml同样会被编译成二进制的XML文件,然后再打包到APK里面去。
  • 应用程序在运行时通过AssetManager来访问资源,或通过资源ID来访问,或通过文件名来访问。

how to package a apk by hand

  • 创建一个android工程
android  create project \
   -n packageTest2 \
   -a MainActivity \
   -k com.package.test2 \
   -t android-23 \
   -p ./PackageTest2
  • 编译R文件
aapt  package \
  -f \
  -J ./gen \
  -M ./AndroidManifest.xml \
  -S ./res/ \
  -I /Users/RadAsm/Library/AndroidSDK/sdk/platforms/android-23/android.jar
  • 编译源代码文件
javac -source 1.6 \
  -target 1.6 \
  -cp /Users/RadAsm/Library/AndroidSDK/sdk/platforms/android-23/android.jar \
  ./src/com/packtest/test1/MainActivity.java ./src/com/packtest/test1/R.java \
  -d ./gen/classes
  • class->dex
 dx --dex \
  --verbose \
  --output ./gen/dex/packtest1.dex 
  ./gen/classes/
  • apk生成
 aapt package 
   -f \
   -J ./gen \
   -M ./AndroidManifest.xml \
   -S ./res/ \
   -I /Users/RadAsm/Library/AndroidSDK/sdk/platforms/android-23/android.jar \
   -F ./output/res.apk
  • 对齐
zipalign -v -p 4 packagetest_unsigned.apk packagetest_aligned_unsigned.apk
  • 签名
apksigner sign --ks my-release-key.jks my-app.apk

推荐阅读更多精彩内容