framework-res.apk覆盖编译方式由RRO替换为SRO

一、问题描述:

android O版本,默认指定了framework-res编译时使用RRO的形式加载资源覆盖,这就导致一些 reference resource 类型的文件,如layout、anim、xml目录中的xml文件,在overlay目录不能进行覆盖,编译时会出现很多类似于

device/bbkedu/H6000/overlay/frameworks/base/core/res/res/layout/safe_mode.xml:17: error: Error: No resource found that matches the given name (at 'background' with value '@drawable/safe_mode_background').

但是我们的systemUI需要定制这些reference resource,所以需要将RRO编译更改为SRO。

二、SRO,RRO相关定义与区别。

1.SRO

即静态Overlay,发生在编译时,需要在Android系统源码环境中进行配置。

2.RRO

即运行时Overlay,该机制的资源替换发生在运行时。

3.区别:

(1)RRO能直接定制替换第三方APK的资源,而不需要其源码。SRO如上节所述,则需要对应APK的源码才能完成,一般而言,第三方是不会提供项目源码的。
(2)RRO的编译结果会得到一个xxx_overlay.apk,加上原项目的apk,总共会有2个apk,而SRO最终只会得到一个已经完成资源替换的apk。得到的overlay.apk可以视为一个正常的apk,因为它能被安装,含有自己的AndroidManifest.xml文件,当然正常下,overlay.apk是不含有执行代码的。
(3)RRO不能替换AndroidManifest.xml文件及reference resource 类型的文件,如layout、anim、xml目录中的xml文件。虽然RRO具有自己的AndroidManifest.xml文件,但它却不能替换源项目中的AndroidManifest.xml文件。关于layout目录中的xml文件,SRO是可以替换的。
以上来源于GrayMonkey:Android Overlay机制


三、RRO是如何引入的

直接看一下几个mk文件:
**device/mediatek/common/device.mk
build/core/definitions.mk
build/core/package_internal.mk**
详细改动如下:

1.device/mediatek/common/device.mk

PRODUCT_ENFORCE_RRO_TARGETS += framework-res

2.build/core/definitions.mk

###########################################################
# Append the information to generate a RRO package for the
# source module.
#
#  $(1): Source module name.
#  $(2): Whether $(3) is a manifest package name or not.
#  $(3): Manifest package name if $(2) is true.
#        Otherwise, android manifest file path of the
#        source module.
#  $(4): Whether LOCAL_EXPORT_PACKAGE_RESOURCES is set or
#        not for the source module.
#  $(5): Resource overlay list.
###########################################################
define append_enforce_rro_sources
  $(eval ENFORCE_RRO_SOURCES += \
      $(strip $(1))||$(strip $(2))||$(strip $(3))||$(strip $(4))||$(call normalize-path-list, $(strip $(5))))
endef

3.build/core/package_internal.mk

enforce_rro_enabled :=
ifneq ($(PRODUCT_ENFORCE_RRO_TARGETS),)
  ifneq ($(package_resource_overlays),)
    ifeq ($(PRODUCT_ENFORCE_RRO_TARGETS),*)
      enforce_rro_enabled := true
    else ifneq (,$(filter $(LOCAL_PACKAGE_NAME), $(PRODUCT_ENFORCE_RRO_TARGETS)))
      enforce_rro_enabled := true
    endif
  endif
  ifdef enforce_rro_enabled
    ifeq (,$(LOCAL_MODULE_PATH))
      ifeq (true,$(LOCAL_PROPRIETARY_MODULE))
        enforce_rro_enabled :=
      else ifeq (true,$(LOCAL_OEM_MODULE))
        enforce_rro_enabled :=
      else ifeq (true,$(LOCAL_ODM_MODULE))
        enforce_rro_enabled :=
      endif
    else ifeq ($(filter $(TARGET_OUT)/%,$(LOCAL_MODULE_PATH)),)
      enforce_rro_enabled :=
    endif
  endif
endif
ifdef enforce_rro_enabled
  ifneq ($(PRODUCT_ENFORCE_RRO_EXCLUDED_OVERLAYS),)
    static_only_resource_overlays := $(filter $(addsuffix %,$(PRODUCT_ENFORCE_RRO_EXCLUDED_OVERLAYS)),$(package_resource_overlays))
    ifneq ($(static_only_resource_overlays),)
      package_resource_overlays := $(filter-out $(static_only_resource_overlays),$(package_resource_overlays))
      LOCAL_RESOURCE_DIR := $(static_only_resource_overlays) $(LOCAL_RESOURCE_DIR)
      ifeq ($(package_resource_overlays),)
        enforce_rro_enabled :=
      endif
    endif
  endif
else
LOCAL_RESOURCE_DIR := $(package_resource_overlays) $(LOCAL_RESOURCE_DIR)
endif
ifdef enforce_rro_enabled
  ifdef LOCAL_EXPORT_PACKAGE_RESOURCES
    enforce_rro_use_res_lib := true
  else
    enforce_rro_use_res_lib := false
  endif
  ifdef LOCAL_MANIFEST_PACKAGE_NAME
    enforce_rro_is_manifest_package_name := true
    enforce_rro_manifest_package_info := $(LOCAL_MANIFEST_PACKAGE_NAME)
  else
    enforce_rro_is_manifest_package_name := false
    enforce_rro_manifest_package_info := $(full_android_manifest)
  endif
$(call append_enforce_rro_sources, \
    $(my_register_name), \
    $(enforce_rro_is_manifest_package_name), \
    $(enforce_rro_manifest_package_info), \
    $(enforce_rro_use_res_lib), \
    $(package_resource_overlays) \
    )
endif  # enforce_rro_enabled

四、修改策略

1.移除 PRODUCT_ENFORCE_RRO_TARGETS += framework-res,仍然使用SRO进行编译,移除后出现报错

out/target/product/H6000/obj/APPS/framework-res_intermediates/flat-res/device/mediatek/common/overlay/telephony/frameworks/base/core/res/res/values-mcc310-mnc260_strings.arsc.flat: error: resource array/wfcOperatorErrorCodes does not override an existing resource.
out/target/product/H6000/obj/APPS/framework-res_intermediates/flat-res/device/mediatek/common/overlay/telephony/frameworks/base/core/res/res/values-mcc310-mnc260_strings.arsc.flat: note: define an <add-resource> tag or use --auto-add-overlay.
error: failed parsing overlays.

从报错信息可以知道,缺少了–auto-add-overlay,于是加上,这时候又一次出错。
framework-res.apk覆盖编译方式由RRO替换为SRO_第1张图片
于是查看了下N版本上framework-res的Android.mk配置,对比发现缺少 -x 这个aapt flag
这里写图片描述


五、最后修改如下:

diff --git a/device/mediatek/common/device.mk b/device/mediatek/common/device.mk
index 8fb4086..d3ad649 100644
--- a/device/mediatek/common/device.mk
+++ b/device/mediatek/common/device.mk
@@ -3347,7 +3347,7 @@ ifneq ($(strip $(MTK_BASIC_PACKAGE)), yes)
DEVICE_PACKAGE_OVERLAYS += device/mediatek/common/overlay/wifitethering_channel
endif

-PRODUCT_ENFORCE_RRO_TARGETS += framework-res
+#PRODUCT_ENFORCE_RRO_TARGETS += framework-res

# Add vendor minijail policy for mediacodec service for Android O
PRODUCT_COPY_FILES += device/mediatek/common/seccomp_policy/mediacodec.policy:$(TARGET_COPY_OUT_VENDOR)/etc/seccomp_policy/mediacodec.policy:mtk
diff --git a/frameworks/base/core/res/Android.mk b/frameworks/base/core/res/Android.mk
index b066929..43c7f96 100644
--- a/frameworks/base/core/res/Android.mk
+++ b/frameworks/base/core/res/Android.mk
@@ -28,7 +28,8 @@ LOCAL_AAPT_FLAGS += --private-symbols com.android.internal

# Framework doesn't need versioning since it IS the platform.
LOCAL_AAPT_FLAGS += --no-auto-version
-
+LOCAL_AAPT_FLAGS += --auto-add-overlay
+LOCAL_AAPT_FLAGS += -x
# Install this alongside the libraries.
LOCAL_MODULE_PATH := $(TARGET_OUT_JAVA_LIBRARIES)

你可能感兴趣的:(Android)