纯命令行打APK实操全记录

介绍

  1. 本文基于ant命令创建工程使用android sdk提供的工具进行手动打包
  2. 打包基本流程
  3. 手动命令打包实操
  4. 后续学习gradle打包、python脚本打包及点击build As的工作过程等

图解打包过程

纯命令行打APK实操全记录_第1张图片
image

手动打包用的工具及环境配置

  1. android.bat

    • 位于sdk的tools目录下

    • 配置环境变量:

      在电脑 --> 属性 --> 高级 --> 环境变量 -->path中加入Android SDK目录中tools目录的路径。实质上就是配置android.bat的目录地址

      例如:我的SDK安装在:D:/AS_SDK/android-sdk-windows下,那就得在path中添加:D:/AS_SDK/android-sdk-windows/tools这样android中一些命令就可以用了。

    • 常用命令:

      配置成功之后可以在cmd中输入android -h 查看android命令支持的功能

      android list targets 查看所有的sdk版本信息

      android list device 查看所有的设备信息

      android create avd 创建一个新的虚拟机

      android
      创建一个Android工程

  2. aapt.exe

    • 位于Android SDK build-tools目录下不同版本中

    • 配置aapt命令环境:

      将某个版本下的aapt.exe的路径加到path中即可,例如:
      C:\Users\DELL\android-sdks\build-tools\26.0.2

    • aapt工具路径为:你的sdk目录\build-tools\aidl.exe

    比如我的在这些工具所在地址:

    D:\AS_SDK\android-sdk-windows\build-tools\26.0.2\aapt.exe
  1. javac.exe

    • 位置D:\jdk1.8\bin
    • javac 类名.java将java文件编译成.class文件
  2. dx.bat

    • 位置:D:\AS_SDK\android-sdk-windows\build-tools\23.0.0
  3. keytool

    生成签名文件,进行签名等

  4. zipalign.exe

    • 位置:D:\AS_SDK\android-sdk-windows\build-tools\23.0.0

    • 对打的包进行压缩优化

打包步骤分解

  1. AAPT打包资源文件,生成应用的R.java文件 + resource.arsc

    资源文件被AAPT(Android Asset Packaging Tool)处理为最终的resources.arsc,并生成R.java文件。以保证源码编写时可以方便的访问这些资源

    • assets是不需要做任何处理的,res/raw只需分配id后与assets一起直接打包到应用程序中;基于下述原因,其它xml文件则会被编译成二进制

    • 编译过程中,会把xml中的字符串进行收集去重,形成字符串资源池,元素中用到字符串的地方将被替换成相应的索引。另外,标签属性/値都会转换为资源id,进一步减少文件大小;

    • 二进制格式的xml把标签属性/値转换为资源id后,避免了字符串解析,从而提高了解析速度;

    • 经过AAPT处理后,会输出2个文件:

      • 一个R.java,为项目各资源分配了不同的id,将和java源码一起参与到后续的编译过程,id为4字节无符号整数,最高字节表示package id,次高字节表示type id,后2字节表示资源在当前类型中出现的序号,如R.string.appname=0x7f07006b中的0x7f代表当前正在编译的资源包,0x07代表string类型,0x006b代表app_name在string类型中出现的序号

      • 另一个为app.ap,实际上为一个压缩包,包含了assets、res、Androidmanifest.xml与resources.arsc

      • 资源索引表resources.arsc记录了从资源id到文件路径的转换关系,当应用通过Resources类获取res文件资源时,会先从resources.arsc中拿到文件路径,然后通过AssetManager进行访问。

  2. 源码编译,打包class文件和jar包为dex文件

    1. 当项目中包含AIDL时,AIDL文件通过AIDL工具转换成编译器能处理的Java接口文件。

      编译AIDL文件的工具在:你的sdk目录\build-tools\aidl.exe。

    2. javac命令将java源码编译成.class字节码,用以编译的classpath包含以下内容:

      • android.jar,具体版本由targetSdkVersion指定;

      • build.gradle中添加的第三方依赖;

    3. 编译后可对代码进行混淆处理,主要包括删除无用类、字节码优化、重命名等操作,只需在build.gradle中配置混淆规则即可

    4. 注意在编译java文件的时候要一同编译R.java文件,否则会出现找不到R文件错误

  3. 将编译后的资源和其他的资源(assets和res资源)打包为资源压缩包(例如res.zip ,名字可以自己定义)

  4. 组合classses.dex和res.zip生成未签名的APK,使用apkbuilder

  5. 生成有签名的APK

  6. 进行zipAlign优化


  1. 创建Android工程目录结构

     android create project -n test -t 1 -p ./CommandBuildApk -k com.thc -a MainActivity
    

    Options:

    -n --name 应用程序的名字
    -t --target SDK Target ID
    -p --path 应用程序的工作目录
    -k --package 应用程序的包名
    -a --activity 默认创建的Activity的名字

    提示:通过 tree 命令可以查看生成的Android工程目录结构

  1. 生成R.java文件

     aapt p -m -J ./gen -M AndroidManifest.xml -S res -I D:/AS_SDK/android-sdk-windows/platforms/android-21/android.jar
    

    Options:

    -f 如果编译出来的文件已经存在,强制覆盖。

    -m 使生成的包的目录放在-J参数指定的目录。

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

    -S res文件夹路径

    -A assert文件夹的路径

    -M AndroidManifest.xml的路径

    -I 某个版本平台的android.jar的路径

    -F 具体指定apk文件的输出

  2. 编译所有的java文件为Java虚拟机认识的.class文件

    使用JDK提供的javac命令进行编译

     javac src/com/thc/apkbuild/*.java gen/com/thc/apkbuild/R.java -bootclasspath d:/AS_SDK/android-sdk-windows/platforms/android-21/android.jar -d bin
     
     //命令解释如下:
     
     javac 
     //包下的java文件
     src/com/thc/apkbuild/*.java 
     //gen目录下的R.java文件
     gen/com/thc/apkbuild/*.java
     //引用android.jar 这个jar包,如果使用其他的jar包,在后面进行添加即可
     -bootclasspath d:/AS_SDK/android-sdk-windows/platforms/android-21/android.jar 
     //打出来的class文件所在目录
     -d bin
     //编码格式 
     -encoding GBK
     //添加jar包
     -classpath /.../xxx.jar
    
     //例如引用Gson的jar包
     javac src/com/thc/apkbuild/*.java gen/com/thc/apkbuild/R.java -d bin -bootclasspath d:/AS_SDK/android-sdk-windows/platforms/android-21/android.jar -classpath libs/gson-2.2.jar
    

    遇到的问题备注: 将java文件编译成class文件的时候一定要记得一起编译gen目录下的R.java文件,否则会报找不到R.java的错误

  3. 打包class文件和第三方jar包为dex文件

     dx --dex --output=bin\classes.dex bin
    
     命令释义:
    
     output=
     
     bin<是class文件和jar包所在的目录> 
    
  4. 编译资源文件生成resources文件

     aapt package -f -M AndroidManifest.xml -S res -A assets -I d:/AS_SDK/android-sdk-windows/platforms/android-21/android.jar -F bin/resources
    
  5. 将编译后的资源和其他的资源(assets和res资源)打包为资源压缩包

    使用aapt工具,命令如下:

     aapt package -f -M AndroidManifest.xml -I d:/AS_SDK/android-sdk-windows/platforms/android-21/android.jar -S res -F my.apk
    

    参数释义在生成R文件的时候有说明。

    到这一步就在你当前目录生成了一个my.apk文件

  6. 将classes.dex和resources加入到生成的apk中

     java -claspath D:\AS_SDK\android-sdk-windows\tools\lib\sdklib.jar com.android.sdklib.build.ApkBuilderMain my.apk -v -u -z bin\resources -f bin\classes.dex -rf src
    

    问题说明: 以前可以直接使用apkbuilder工具直接打包,但是目前sdk将该工具移除了。其实apkbuilder最终调用的是sdklib.jar中的com.android.sdklib.build.ApkBuilderMain类来做事情的,所以这里直接通过 java 来使用ApkBuilderMain这个类,来把resources和classes.dex加入到apk文件中

  7. 生成有签名的APK

    1. 生成签名:

       keytool -genkey -alias <别名> -keyalg RSA -validity 20000 -keystore <签名.keystore>
      
    2. 给apk签名

       jarsigner -verbose -keystore <签名.keystore> -signedjar <签名ed.apk> <未签名.apk> <别名>  
      
    3. 注意: 在给apk签名的时候的命令是-signedjar

  8. 进行zipAlign优化

     zipalign -f 4 my_signed.apk my_signed_optimizated.apk
    
  9. 安装到手机

    adb install -r my_signed_optimizated.apk
    

关于apkbuilder

参考(mac版本)

参考1 知乎

参考2

参考3

关于android命令

Android构建过程分析

浅析 Android 打包流程

你可能感兴趣的:(纯命令行打APK实操全记录)