博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
用Android SDK Build Tools手动构建APK
阅读量:6582 次
发布时间:2019-06-24

本文共 3770 字,大约阅读时间需要 12 分钟。

我们平时都是用Android Studio进行Android应用的开发,Android Studio构建APK是通过调用Gradle脚本实现的,而Gradle脚本最终是通过调用Android SDK Build Tools里的各种命令行工具实现的。

下面尝试直接用Build Tools构建一个极简的Hello World APK,了解一下这个过程和各个工具的基本用法。

整个构建过程大致分为以下几步:

  1. 用aapt2编译资源文件,生成中间二进制文件
  2. 用aapt2链接合并中间文件,生成不包含代码的APK,并生成R.java
  3. 用javac编译java源文件,得到.class java字节码文件
  4. 用d8将.class编译成DEX字节码文件
  5. 将DEX文件导入APK中
  6. 对APK进行签名

创建项目源文件

项目的目录结构及文件源码如下:

D:\helloworld>tree /F│ AndroidManifest.xml│├─compiled│├─java│  └─com│      └─cdjtest│          └─helloworld│                  MainActivity.java│└─res    ├─drawable    │      ic_launcher.png    │    ├─layout    │      activity_main.xml    │    └─values           strings.xml复制代码

AndroidManifest.xml

复制代码

MainActivity.java

package com.cdjtest.helloworld;import android.app.Activity;import android.os.Bundle;public class MainActivity extends Activity {    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);    }}复制代码

activity_main.xml

复制代码

strings.xml

helloworld
复制代码

用aapt2编译资源文件

先设置一下环境变量,将Build Tools 28.0.3的路径加到PATH中,方便调用

D:\helloworld>set PATH=%PATH%;$ANDROID_HOME%\build-tools\28.0.3\复制代码

编译res目录下的3个资源文件,生成.flat中间二进制文件

D:\helloworld>aapt2 compile res\values\strings.xml -o compiled\D:\helloworld>aapt2 compile res\layout\activity_main.xml -o compiled\D:\helloworld>aapt2 compile res\drawable\ic_launcher.png -o compiled\复制代码

链接.flat文件,生成helloworld.unsigned.apk(还未包含DEX字节码),--java java参数指定在java目录生成R.java文件,和MainActivity.java在同一目录

D:\helloworld>aapt2 link -o helloworld.unsigned.apk ^    -I %ANDROID_HOME%\platforms\android-28\android.jar ^    compiled\values_strings.arsc.flat ^    compiled\layout_activity_main.xml.flat ^    compiled\drawable_ic_launcher.png.flat ^    --manifest AndroidManifest.xml --java java\复制代码

用javac和d8编译源码

用javac将MainActivity.java和R.java编译成.class文件

D:\helloworld>javac java\com\cdjtest\helloworld\*.java -classpath %ANDROID_HOME%\platforms\android-28\android.jar复制代码

用d8将.class编译成classes.dex,(d8和dx的对比可参考Jake大神的)

D:\helloworld>d8 --lib %ANDROID_HOME%\platforms\android-28\android.jar --release --output . java\com\cdjtest\helloworld\*.class复制代码

classes.dex导入APK中

D:\helloworld>aapt add helloworld.unsigned.apk classes.dex复制代码

APK签名

用zipalign优化APK,主要作用是内存对齐,提高运行时读取资源的效率

D:\helloworld>zipalign -p 4 helloworld.unsigned.apk helloworld.unsigned.aligned.apk复制代码

用JDK自带的keytool工具生成keystore文件my-release-key.jks

D:\helloworld>keytool -genkey -v -keystore my-release-key.jks -keyalg RSA -keysize 2048 -validity 10000 -alias my-alias复制代码

用apksigner和my-release-key.jks签名APK,生成helloworld-release.apk

D:\helloworld>apksigner sign --ks my-release-key.jks --out helloworld-release.apk helloworld.unsigned.aligned.apkKeystore password for signer #1:复制代码

最终的目录结构:

D:\helloworld>tree /F│  AndroidManifest.xml│  classes.dex│  helloworld-release.apk│  helloworld.unsigned.aligned.apk│  helloworld.unsigned.apk│  my-release-key.jks│├─compiled│      drawable_ic_launcher.png.flat│      layout_activity_main.xml.flat│      values_strings.arsc.flat│├─java│  └─com│      └─cdjtest│          └─helloworld│                  MainActivity.class│                  MainActivity.java│                  R$drawable.class│                  R$layout.class│                  R$string.class│                  R.class│                  R.java│└─res    ├─drawable    │      ic_launcher.png    │    ├─layout    │      activity_main.xml    │    └─values            strings.xml复制代码

安装APK

D:\helloworld>adb install helloworld-release.apkSuccess复制代码

成功运行屏幕中间可见"Hello World!"。

参考资料:

转载于:https://juejin.im/post/5cc82110e51d456e79545d0e

你可能感兴趣的文章
js混淆 反混淆 在线
查看>>
Linux ftp
查看>>
大规模分布式数据处理平台Hadoop的介绍 一种可靠、高效、可伸缩的处理方案
查看>>
python中的Iterable, Iterator,生成器概念
查看>>
WinForm 之 程序启动不显示主窗体
查看>>
ios硬件编码
查看>>
【Network】Calico, Flannel, Weave and Docker Overlay Network 各种网络模型之间的区别
查看>>
【转】Oracle索引的类型
查看>>
FragmentTransaction.replace() 你不知道的坑
查看>>
分布式消息队列 Kafka
查看>>
模拟退火算法
查看>>
Solr 按照得分score跟指定字段相乘排序
查看>>
GoogleMapsV3-----基础地图(自定义消息提示OverlayView) (转)
查看>>
create database link
查看>>
shouldAutoRotate Method Not Called in iOS6
查看>>
Sql Server系列:Transact-SQL变量
查看>>
ADF_Database Develop系列1_通过UML数据库开发之建Logical UML Class Model
查看>>
SQL Server表分区的NULL值问题
查看>>
JavaScript学习笔记——DOM_对document对象的内容、属性、样式的操作
查看>>
Linux系统调用
查看>>