1. 程式人生 > >Overlay機制

Overlay機制

Android overlay 機制允許在不修改packages中apk的情況下,來自定義 framework和package中的資原始檔,實現資源的定製。來達到顯示不同UI得目的(如MIUI)。 

    以下幾類能夠通過該機制定義:

  • Configurations (string, bool, bool-array)
  • Localization (string, string-array)
  • UI Appearance (color, drawable, layout, style, theme, animation)
  • Raw resources (audio, video, xml)

For detailed introduction on Android application resources, please refer to:

1 為產品新增Overlay目錄

1.1 Product Overlays與Device Overlays

有兩種不同的overaly目錄定義,來影響最終的效果:

  • PRODUCT_PACKAGE_OVERLAYS: used by a particular product
  • DEVICE_PACKAGE_OVERLAYS: used several products that share a common device model

如果包含同一資源,那麼 PRODUCT_PACKAGE_OVERLAYS 將覆蓋 DEVICE_PACKAGE_OVERLAYS 中的, 這兩個定義如下:

build/core/package.mk (Line: 93)

LOCAL_RESOURCE_DIR := \

  $(wildcard $(foreach dir, $(PRODUCT_PACKAGE_OVERLAYS), \

    $(addprefix $(dir)/, $(LOCAL_RESOURCE_DIR)))) \

  $(wildcard $(foreach dir, $(DEVICE_PACKAGE_OVERLAYS), \

    $(addprefix $(dir)/, $(LOCAL_RESOURCE_DIR)))) \

  $(LOCAL_RESOURCE_DIR)

PRODUCT_PACKAGE_OVERLAYS & DEVICE_PACKAGE_OVERLAYS 功能是一樣的,只是優先順序不一樣:

    PRODUCT_PACKAGE_OVERLAYS 優先於 DEVICE_PACKAGE_OVERLAYS

1.2 改變makefile來新增overlays的編譯項

為了新增一個overlay目錄, 需要修改產品的makefile 

(for example:device/vendor-name/device-name/product-name.mk

新增以下幾行:

PRODUCT_PACKAGE_OVERLAYS :=  device/vendor-name/device-name/product-name/overlay $(PRODUCT_PACKAGE_OVERLAYS)

Or:

DEVICE_PACKAGE_OVERLAYS :=  device/vendor-name/device-name/common/overlay $(DEVICE_PACKAGE_OVERLAYS)

(如:device/vendor-name/device-name/device_base.mk)中新增: 

LOCAL_PATH := device/vendor-name/device-name

DEVICE_PACKAGE_OVERLAYS := $(LOCAL_PATH)/overlay

如果要定義多個overlays目錄,需要用空格隔開. 

如果有多個目錄,並且都包含同一資源的定義,那麼將使用第一個定義的目錄中的資源。

1.3 在overlay目錄下建立資原始檔

   想覆蓋Android系統自帶package中資原始檔, 那麼在overlay目錄下必須包含和要替換package相同的路徑, 該路徑是Android原始碼目錄的相對路徑.

For example, 如果我們想要替換以下目錄的資原始檔:

packages/apps/Settings/res/

那麼在overlay目錄下面必須建立一樣的目錄:

....../overlay目錄/packages/apps/Settings/res/

然後放入想要替換的資源(必須和系統package相同路徑和檔名).

注意:

  • For color, bool, string, array, style/theme types, the resource values are identifed by their keys, so for these types, there is no need to put the resources in a file with the same name as in the original base package.
  • For layout, animation, picture drawables and raw types, the resources are indentifed by their file name, and overlay for these resources should keep the file name same as in the base packages.

2 在APK中檢測資源

   通過overlay改變apk資原始檔並生成apk後,一般要檢測生成的apk的資源是否已經改變了.

2.2 使用AAPT檢測

Usage:
aapt l[ist] [-v] [-a] file.{zip,jar,apk}
   List contents of Zip-compatible archive.
aapt d[ump] [--values] WHAT file.{apk} [asset [asset ...]]
   badging          Print the label and icon for the app declared in APK.
   permissions      Print the permissions from the APK.
   resources        Print the resource table from the APK.
   configurations   Print the configurations in the APK.
   xmltree          Print the compiled xmls in the given assets.
   xmlstrings       Print the strings of the given compiled xml assets.

For example:

1. To dump string, bool values:

aapt dump resources Settings.apk

2. To dump a raw xml file:

aapt dump xmltree Settings.apk res/xml/appwidget_info.xml

3. To dump the current configurations/localizations:

aapt dump configurations Settings.apk

2.2 使用apktools檢測

Apktool v1.5.0.5a056e3 - a tool for reengineering Android apk files
Copyright 2010 Ryszard Wi??niewski
with smali v1.3.4-ibot8, and baksmali v1.3.4-ibot8
Updated by iBotPeaches
Apache License 2.0 (http://www.apache.org/licenses/LICENSE-2.0)
Usage: apktool [-q|--quiet OR -v|--verbose] COMMAND [...]
COMMANDs are:
    d[ecode] [OPTS] [
        Decode to
        OPTS:
        -s, --no-src
            Do not decode sources.
        -r, --no-res
            Do not decode resources.
        -d, --debug
            Decode in debug mode. Check project page for more info.
        -f, --force
            Force delete destination directory.
        -t , --frame-tag
            Try to use framework files tagged by .
        --keep-broken-res
            Use if there was an error and some resources were dropped, e.g.:
            "Invalid config flags detected. Dropping resources", but you
            want to decode them anyway, even with errors. You will have to
            fix them manually before building.
    b[uild] [OPTS] [] []
        Build an apk from already decoded application located in .
        It will automatically detect, whether files was changed and perform
        needed steps only.
        If you omit then current directory will be used.
        If you omit then /dist/
        will be used.
        OPTS:
        -f, --force-all
            Skip changes detection and build all files.
        -d, --debug
            Build in debug mode. Check project page for more info.
    if|install-framework []
        Install framework file to your system.
For additional info, see: https://github.com/iBotPeaches/brut.apktool
For smali/baksmali info, see: http://code.google.com/p/smali/

2.3 Using dumpres

3 More on AAPT and Overlay

3.1 How overlay works

While building the package APKs, the overlay directories are passed to aapt command lines using -S options in the same order as they are defined in 

PRODUCT_PACKAGE_OVERLAYS and DEVICE_PACKAGE_OVERLAYS.

For example, while building the Settings APK, the following command are executed:

out/host/linux-x86/bin/aapt package -u  -z \
         -M packages/apps/Settings/AndroidManifest.xml \
         -S device/vendor-name/device-name/product-name/overlay/packages/apps/Settings/res \
         -S vendor/vendor-name/media/common/overlay/packages/apps/Settings/res -S packages/apps/Settings/res \
         -I out/target/common/obj/APPS/framework-res_intermediates/package-export.apk \
         --min-sdk-version 16 --target-sdk-version 16 --product default \
         --version-code 16 --version-name 4.1.2-eng.xxxx.20121121.152327 \
         -F out/target/product/product-name/obj/APPS/Settings_intermediates/package.apk

Note: some overlay directories that don't contain the Settings resources will be filtered first, and do not appear in the above command line.

3.2 Add extra resources in Overlay

Though not recommanded, we can add new resources in overlay directory, for example, if base package Settings doesn't define a bool value with key no_such_key, we can add it in the overlay file bool.xml like this:

   ... ...
    true
    ... ...

If the add-resource line is missing, aapt tool will complain while creating the apk file:

device/vendor-name/device-name/product-name/overlay/packages/apps/Settings/res/values/bools.xml:30: error: Resource at no_such_key appears in overlay but \
not in the base package; use to add.

Another way to avoid the complaint is to run aapt with the option:

--auto-add-overlay
    Automatically add resources that are only in overlays.