用Android SDK Build Tools手动构建APK

栏目: IOS · Android · 发布时间: 6年前

内容简介:我们平时都是用Android Studio进行Android应用的开发,Android Studio构建APK是通过调用Gradle脚本实现的,而Gradle脚本最终是通过调用Android SDK Build Tools里的各种命令行工具实现的。下面尝试直接用Build Tools构建一个极简的Hello World APK,了解一下这个过程和各个工具的基本用法。整个构建过程大致分为以下几步:

我们平时都是用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

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.cdjtest.helloworld">
    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@android:style/Theme">
        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>
</manifest>
复制代码

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

<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:gravity="center"
    android:text="Hello World!"/>
复制代码

strings.xml

<resources>
    <string name="app_name">helloworld</string>
</resources>
复制代码

用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.apk
Keystore 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.apk
Success
复制代码

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

参考资料:


以上所述就是小编给大家介绍的《用Android SDK Build Tools手动构建APK》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

Dynamic Programming

Dynamic Programming

Richard Bellman / Dover Publications / 2003-03-04 / USD 19.95

An introduction to the mathematical theory of multistage decision processes, this text takes a "functional equation" approach to the discovery of optimum policies. The text examines existence and uniq......一起来看看 《Dynamic Programming》 这本书的介绍吧!

UNIX 时间戳转换
UNIX 时间戳转换

UNIX 时间戳转换

正则表达式在线测试
正则表达式在线测试

正则表达式在线测试

HEX CMYK 转换工具
HEX CMYK 转换工具

HEX CMYK 互转工具