1、簡介
Android支持各種各樣的資源,如何使用這些資源,官方開發者指南已給出了詳細的用法說明,可參考https://developer.android.com/guide/topics/resources/providing-resources,本文說明Android資源管理的原理。Android支持aapt和jack兩種編譯方式,資管原理包括Asset和Resource兩個重要的模塊。
2、apk打包流程
首先來看一下使用了aapt的apk打包流程,如下圖。
3、aapt
aapt的用法可參考【Android】玩轉命令行工具-aapt2(https://blog.csdn.net/iEearth/article/details/84632797)。
aapt源碼位置如下:
frameworks/base/tools/aapt(deprecated)
frameworks/base/tools/aapt2
從aapt2的Main.cpp中可以看出,aapt2包括六大部分,分別是Compile、Link、Dump、Diff、Optimize和Convert,代碼如下:
extern int Compile(const std::vector<StringPiece>& args, IDiagnostics* diagnostics);
extern int Link(const std::vector<StringPiece>& args, IDiagnostics* diagnostics);
extern int Dump(const std::vector<StringPiece>& args);
extern int Diff(const std::vector<StringPiece>& args);
extern int Optimize(const std::vector<StringPiece>& args);
extern int Convert(const std::vector<StringPiece>& args);
static int ExecuteCommand(const StringPiece& command, const std::vector<StringPiece>& args,
IDiagnostics* diagnostics) {
if (command == "compile" || command == "c") {
return Compile(args, diagnostics);
} else if (command == "link" || command == "l") {
return Link(args, diagnostics);
} else if (command == "dump" || command == "d") {
return Dump(args);
} else if (command == "diff") {
return Diff(args);
} else if (command == "optimize") {
return Optimize(args);
} else if (command == "convert") {
return Convert(args);
} else if (command == "version") {
PrintVersion();
return 0;
}
diagnostics->Error(DiagMessage() << "unknown command '" << command << "'");
return -1;
}
apk本身是個jar包,hello.apk: Java archive data (JAR),在Linux上解壓這個jar包,內容如下(文件後面列出了文件格式):
├── AndroidManifest.xml Android binary XML
├── classes.dex Dalvik dex file version 038
├── META-INF
│ ├── CERT.RSA data
│ ├── CERT.SF ASCII text, with CRLF line terminators
│ └── MANIFEST.MF ASCII text, with CRLF line terminators
├── res
│ ├── drawable
│ │ ├── ic_launcher_background.xml Android binary XML
│ │ ├── hello.png PNG image data, 260 x 180, 8-bit/color RGBA, non-interlace
│ ├── drawable-v24
│ │ ├── ic_launcher_foreground_1.xml Android binary XML
│ │ └── ic_launcher_foreground.xml Android binary XML
│ ├── layout
│ │ ├── activity_main.xml Android binary XML
│ ├── mipmap-anydpi-v26
│ │ ├── ic_launcher_round.xml Android binary XML
│ │ └── ic_launcher.xml Android binary XML
│ ├── mipmap-hdpi-v4
│ │ ├── ic_launcher.png PNG image data, 72 x 72, 8-bit/color RGBA, non-interlaced
│ │ └── ic_launcher_round.png PNG image data, 72 x 72, 8-bit/color RGBA, non-interlaced
│ ├── mipmap-mdpi-v4
│ │ ├── ic_launcher.png PNG image data, 48 x 48, 8-bit/color RGBA, non-interlaced
│ │ └── ic_launcher_round.png PNG image data, 48 x 48, 8-bit/color RGBA, non-interlaced
│ ├── mipmap-xhdpi-v4
│ │ ├── ic_launcher.png PNG image data, 96 x 96, 8-bit/color RGBA, non-interlaced
│ │ └── ic_launcher_round.png PNG image data, 96 x 96, 8-bit/color RGBA, non-interlaced
│ ├── mipmap-xxhdpi-v4
│ │ ├── ic_launcher.png PNG image data, 144 x 144, 8-bit/color RGBA, non-interlaced
│ │ └── ic_launcher_round.png PNG image data, 144 x 144, 8-bit/color RGBA, non-interlaced
│ └── mipmap-xxxhdpi-v4
│ ├── ic_launcher.png PNG image data, 192 x 192, 8-bit/color RGBA, non-interlaced
│ └── ic_launcher_round.png PNG image data, 192 x 192, 8-bit/color RGBA, non-interlaced
└── resources.arsc data
資源解析爲R.java時,各種資源的ID格式爲:0XAABBCCCC,其中AA爲01時表示系統資源,AA爲7f時表示apk內部的資源;BB表示資源類型,如attr、id、style、string等。
4、jack
jack是Android的一個試驗品,爲了加快編譯速度,有自己的文件格式,支持的版本爲Android 6.0-8.1,由於java8的語言特性,現已廢棄jack,可參考:https://source.android.google.cn/setup/build/jack。
5、資源加載流程
關於資源加載流程,以View的background爲例進行說明,流程如下。
6、AssetManager
從上文可以看出AssetManager是一個很重要的模塊,AssetManager用來管理資源。下面來看看AssetManager在初始化時做了哪些事情。