创建工程
//MainActivity.java
package com.qsc.hello;
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"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal">
<TextView
android:id="@+id/sample_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello World!" />
</LinearLayout>
//AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.qsc.hello">
<uses-sdk
android:minSdkVersion="21"
android:targetSdkVersion="28" />
<application
android:icon="@drawable/ic_launcher"
android:label="MyFirstApp">
<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>
工程目录结构图:
使用aapt编译资源
为什么资源也需要编译?其实二进制的资源(比如图片)是不需要编译的,只不过这个"编译"的行为是为了生成resources.arsc和对xml文件进行二进制化等操作,resources.arsc是一张表,里面记录了资源id和其对应的资源,Android为我们提供了R这个类,指定了资源索引(id),根据id就可以从resources.arsc表内查找到具体的资源,xml二进制化是为了系统读取上性能更好。
官方文档
https://developer.android.com/studio/command-line/aapt2
要在 Linux 或 Mac 上从命令行使用 AAPT2,请运行 aapt2
命令。在 Windows 上,请运行 aapt2.exe
命令。AAPT2 支持通过启用增量编译实现更快的资源编译。这是通过将资源处理拆分为两个步骤来实现的:
- [编译]:将资源文件编译为二进制格式。
- [链接]:合并所有已编译的文件并将它们打包到一个软件包中。
这种拆分方式有助于提高增量编译的性能。例如,如果一个文件发生了改变,则只需要重新编译这个文件。
编译
//编译activity_main.xml
E:\HelloDemo>aapt2.exe compile src\main\res\layout\activity_main.xml -o compiled
//编译ic_launcher.png
E:\HelloDemo>aapt2.exe compile src\main\res\drawable\ic_launcher.png -o compile
d
在compiled文件夹中,我们看到多了两个文件drawable_ic_launcher.png.flat和layout_activity_main.xml.flat,flat理解为一个中间产物即可,是aapt2特有的,aapt没有,aapt2用它能进行增量编译。
链接
E:\HelloDemo>aapt2.exe link -o resources.ap_ -I %ANDROID_HOME%\platforms\android
-28\android.jar compiled\layout_activity_main.xml.flat compiled\drawable_ic_laun
cher.png.flat --java src\main\java --manifest src\main\AndroidManifest.xml
经过这一步骤,会生成resources.ap_和R.java
编译java文件
E:\HelloDemo>javac -d build -cp %ANDROID_HOME%\platforms\android-28\android.jar
src\main\java\com\qsc\hello\*.java
可以看见我们的 class 文件就出来了。里面有 MainActivity、R,还有 R 的内部类 R$layout等,我们开始执行 dex 转换
dx化
E:\HelloDemo>E:\Sdk\build-tools\28.0.3\dx.bat --dex --output=classes.dex build
我们在当前目录下就得到了一个 classes.dex 文件。
生成未签名的apk
一个正常apk的结构
1.classes.dex
2.资源文件
3.resources.arsc
4.签名摘要
5.可选的 assets 等
我们先把前面3个合起来,这个很简单,首先对我们利用 aapt 构造出来的ap_文件,复制一份,重命名成 app-debug.apk 文件,然后把classes.dex加进去。
其实现在我们的 app-debug-unsigned.apk 是做完了。可以安装试一下,但是输出如下:
E:\HelloDemo>adb install app-debug.apk
adb: failed to install app-debug.apk: Failure [INSTALL_PARSE_FAILED_NO_CERTIFICA
TES: Failed to collect certificates from /data/app/vmdl1588008211.tmp/base.apk:
Attempt to get length of null array]
签名apk
没有证书信息,我们其实可以用android debug key进行签名,这样最简单,我们可以看一下怎么签名呢,我们要用到apksigner这个工具
E:\HelloDemo>E:\Sdk\build-tools\28.0.3\apksigner.bat sign -ks C:\Users\Lanxumit\
.android\debug.keystore app-debug.apk
这时候会让我们输入密码,我们输入android即可。
再次安装apk,安装成功!
E:\HelloDemo>adb install app-debug.apk
Success