【Android】圖文解密Android Resource&Asset

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在初始化時做了哪些事情。

在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章