添加系统级res资源包

//

刚做完自定义res资源包的配置,这里做一下关于在配置过程中出现的问题和解决方法作一下记录。

资源的引用格式为:

@包名:资源类型/资源名

以framework资源为例:

@android:style/Theme.Holo.Light

这次需要配置与framework同级的资源包,以包名为"custemer"为例,配置完成后资源引用:

@custemer:style/Theme.Holo.Light
一、新建自定义资源包
  1. 在framework/base/core/下新建名为“res_custemer”文件夹,结构如下:
  2. 编写Android.mk/Android.bp文件
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)# include apicheck.mk later, we need the build pass to prepare the first version
# include $(LOCAL_PATH)/apicheck.mk
LOCAL_PACKAGE_NAME := custemer-res
LOCAL_CERTIFICATE := platform
LOCAL_AAPT_FLAGS := -x3# Tell aapt to build resource in utf16(the ROM will be enlarged),
# in order to save RAM size for string cache table
ifeq (yes,strip$(MTK_GMO_RAM_OPTIMIZE))
LOCAL_AAPT_FLAGS += --utf16
endifLOCAL_NO_CUSTEMERRES := true
LOCAL_MODULE_TAGS := optional
# Install this alongside the libraries.
LOCAL_MODULE_PATH := $(TARGET_OUT_JAVA_LIBRARIES)
# Create package-export.apk, which other packages can use to get
# PRODUCT-agnostic resource data like IDs and type definitions.
LOCAL_EXPORT_PACKAGE_RESOURCES := true
include $(BUILD_PACKAGE)# define a global intermediate target that other module may depend on.
.PHONY: gome-res-package-target
gome-res-package-target: $(LOCAL_BUILT_MODULE)

"LOCAL_AAPT_FLAGS := -x3 " value 的定义需要与 "frameworks\base\libs\androidfw\ResourceTypes.cpp"中 所定义的resource ID 一致

//
// Copyright (C) 2008 The Android Open Source Project
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//android_app {name: "xxx-res", certificate: "platform",platform_apis: true,// Soong special-cases framework-res to install this alongside// the libraries at /system/framework/framework-res.apk.// Generate private symbols into the com.android.internal.R class// so they are not accessible to 3rd party apps.aaptflags: [// Framework doesn't need versioning since it IS the platform."--no-auto-version",// Allow overlay to add resource"--auto-add-overlay",// Add for xxx"--package-id 0x0a","--private-symbols","com.xxx.internal",],owner: "xxx",// Create package-export.apk, which other packages can use to get// PRODUCT-agnostic resource data like IDs and type definitions.export_package_resources: true,defaults: ["getxxxResManifest"],
}bootstrap_go_package {name: "soong-getxxxResManifest",pkgPath: "android/soong/getxxxResManifest",deps: ["blueprint","blueprint-pathtools","soong","soong-android","soong-cc","soong-genrule","soong-apex",],srcs: ["getxxxResManifest.go",],pluginFor: ["soong_build"],
}getSunmiResManifest {name: "getxxxResManifest",
}
  1. 编写AndroidManifest.xml文件
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"package="custemer" coreApp="true" android:sharedUserId="android.uid.system"android:sharedUserLabel="@null"><eat-comment /><protected-broadcast android:name="android.intent.action.SCREEN_OFF" /><permission android:name="android.permission.ADVANCED_WIDGET_API"android:protectionLevel="normal" /><application android:process="system"android:persistent="true"android:hasCode="false"android:label="@null"android:allowClearUserData="false"android:killAfterRestore="false"android:icon="@null"></application></manifest>

"custemer" 为资源包名

二、添加编译依赖关系

framework_custemer_res_package_export :=
framework_custemer_res_package_export_deps :=ifneq ($(LOCAL_PACKAGE_NAME), mediatek-res)framework_custemer_res_package_export += \$(call intermediates-dir-for,APPS,mediatek-res,,COMMON)/package-export.apkframework_custemer_res_package_export_deps += \$(call intermediates-dir-for,APPS,mediatek-res,,COMMON)/src/R.stampifneq ($(LOCAL_PACKAGE_NAME),custemer-res)framework_custemer_res_package_export += \$(call intermediates-dir-for,APPS,gome-res,,COMMON)/package-export.apkframework_custemer_res_package_export_deps += \$(call intermediates-dir-for,APPS,gome-res,,COMMON)/src/R.stampendif
endif# FIXME: Cannot set in Android.mk due to base_rules.mk#ifneq ($(LOCAL_PACKAGE_NAME),mediatek-res)#   LOCAL_RES_LIBRARIES += mediatek-res#endif
....
$(filter-out $(framework_gome_res_package_export),$(resource_export_package)): $(framework_custemer_res_package_export_deps )
$(R_file_stamp): $(framework_custemer_res_package_export_deps )$(resource_export_package) $(R_file_stamp) $(LOCAL_BUILT_MODULE): $(all_library_res_package_export_deps)
$(LOCAL_INTERMEDIATE_TARGETS): \PRIVATE_AAPT_INCLUDES := $(all_library_res_package_exports) $(framework_custemer_res_package_export )

将 mediatek-res与自定义资源模块名定义在一起,否则编译时会出现circle dependence的错误;
将 framework_gome_res_package_export 添加进 PRIVATE_AAPT_INCLUDES 中,否则应用运行会报找不到资源的错误。

三、将资源路径添加进framework编译

路径: frameworks/base/Android.mk

framework_res_source_path := APPS/framework-res_intermediates/src
# M:add mediatek resource path
mediatek-res-source-path := APPS/mediatek-res_intermediates/src
gome_custemer_source_path := APPS/custemer-res_intermediates/src
...
LOCAL_INTERMEDIATE_SOURCES := \$(framework_res_source_path)/android/R.java \$(framework_res_source_path)/android/Manifest.java \$(framework_res_source_path)/com/android/internal/R.java
# M:add mediatek resource R.java into framework,@{
LOCAL_INTERMEDIATE_SOURCES += \$(mediatek-res-source-path)/com/mediatek/internal/R.java \$(mediatek-res-source-path)/com/mediatek/R.java \$(mediatek-res-source-path)/com/mediatek/Manifest.java
# @}# M:add custemer resource R.java into framework,@{
LOCAL_INTERMEDIATE_SOURCES += \$(custemer_res_source_path)/com/gome/internal/R.java \$(custemer_res_source_path)/com/gome/R.java \$(custemer_res_source_path)/com/gome/Manifest.java
# @}LOCAL_MODULE := framework# Make sure that R.java and Manifest.java are built before we build
# the source for this library.
framework_res_R_stamp := \$(call intermediates-dir-for,APPS,framework-res,,COMMON)/src/R.stamp
$(full_classes_compiled_jar): $(framework_res_R_stamp)
$(built_dex_intermediate): $(framework_res_R_stamp)
# M:add mediatek resource dependes framework->mediatek_res->framework_res,@{
mediatek_res_R_stamp := \$(call intermediates-dir-for,APPS,mediatek-res,,COMMON)/src/R.stamp
$(full_classes_compiled_jar): $(mediatek_res_R_stamp)
$(built_dex_intermediate): $(mediatek_res_R_stamp)
custemer_res_R_stamp := \$(call intermediates-dir-for,APPS,custemer-res,,COMMON)/src/R.stamp
$(full_classes_compiled_jar): $(custemer_res_R_stamp)
$(built_dex_intermediate): $(custemer_res_R_stamp)
# @}
四、修改 PackageManagerService

路径:frameworks\base\services\core\java\com\android\server\pm\PackageManagerService.java

   ApplicationInfo mAndroidApplication;/// M: [CIP] Add application info for mediatek-res.apkApplicationInfo mMediatekApplication;ApplicationInfo mCustemerApplication;private PackageParser.Package scanPackageDirtyLI(PackageParser.Package pkg,final int policyFlags, final int scanFlags, long currentTime, UserHandle user)throws PackageManagerException {    /** M: [CIP] skip duplicated mediatek-res.apk @{ *//// This will replace original resources with CIP resourcesif (pkg.packageName.equals("com.mediatek")) {synchronized (mPackages) {if (mMediatekApplication != null) {Slog.w(TAG, "*************************************************");Slog.w(TAG, "Core mediatek package being redefined.  Skipping.");Slog.w(TAG, " file=" + scanFile);Slog.w(TAG, "*************************************************");throw new PackageManagerException(INSTALL_FAILED_DUPLICATE_PACKAGE,"Core android package being redefined.  Skipping.");}mMediatekApplication = pkg.applicationInfo;}}/** @} */if (pkg.packageName.equals("custemer")) {synchronized (mPackages) {if (mCustemerApplication != null) {Slog.w(TAG, "*************************************************");Slog.w(TAG, "Core gome package being redefined.  Skipping.");Slog.w(TAG, " file=" + scanFile);Slog.w(TAG, "*************************************************");throw new PackageManagerException(INSTALL_FAILED_DUPLICATE_PACKAGE,"Core android package being redefined.  Skipping.");}mCustemerApplication = pkg.applicationInfo;}}}
五、预置自定义资源包

目录:device/mediatek/common/device.mk

# for mediatek-res
PRODUCT_PACKAGES += mediatek-res# for custemer-res
PRODUCT_PACKAGES += custemer-res
六、修改资源管理器 Assetmanager.cpp

目录:framework/base/libs/androidfw/AssetManager.cpp

///M:add the resource path
static const char* kMediatekAssets = "/vendor/framework/mediatek-res/mediatek-res.apk";
///M:add the resource path
static const char* kCustemerAssets = "framework/custemer-res/custemer-res.apk";bool AssetManager::addDefaultAssets()
{const char* root = getenv("ANDROID_ROOT");LOG_ALWAYS_FATAL_IF(root == NULL, "ANDROID_ROOT not set");...if((fp= fopen(pathCip,"w+"))!= NULL) {.....return isOK1;} else {//ALOGD("AssetManager-->addDefaultAssets CIP path not exsit!");String8 path(root);path.appendPath(kSystemAssets);///M:add the new resource path into default path,so all the app can reference,@{bool isOK1 = addAssetPath(path, NULL, false /* appAsLib */, true /* isSystemAsset */);String8 path2(kMediatekAssets);bool isOK2 = addAssetPath(path2, NULL, false, false);String8 path3(root);path3.appendPath(kCustemerAssets);bool isOK3 =addAssetPath(path3, NULL, false, false);if(!isOK3){ALOGW("AssetManager-->addDefaultAssets isok3 is false");}else{ALOGW("AssetManager-->addDefaultAssets isok3 is true");}

将自定义资源apk添加进系统资源管理器,当应用使用自定义资源id查找资源时,会通过AssetManager来查找。如果这里写错会导致会先各种问题。以字符串为例,当应用通过R.strings.xxx来查找字符串时,由于AssetManager无法返回正确的资源,默认会返回资源的id值。

六、修改 ResourceTypes.cpp,添加对应的package id
#define APP_PACKAGE_ID      0x7f
#define SYS_MTK_PACKAGE_ID  0x08 /// M: 0x08 is mediatek-res.apk resource ID
#define SYS_CUSTEMER_PACKAGE_ID  0x03 // 0x03 is gome-res.apk resource ID
#define SYS_PACKAGE_ID      0x01bool ResTable::stringToValue(Res_value* outValue, String16* outString,const char16_t* s, size_t len,bool preserveSpaces, bool coerceType,uint32_t attrID,const String16* defType,const String16* defPackage,Accessor* accessor,void* accessorCookie,uint32_t attrType,bool enforcePrivate) const
{if (*s == '@') {....} else {if (rid != 0) {uint32_t packageId = Res_GETPACKAGE(rid) + 1;if (packageId != APP_PACKAGE_ID && packageId != SYS_PACKAGE_ID && packageId != SYS_MTK_PACKAGE_ID && packageId != SYS_CUSTEMER_PACKAGE_ID) {outValue->dataType = Res_value::TYPE_DYNAMIC_REFERENCE;}outValue->data = rid;return true;}if (accessor) {uint32_t rid = accessor->getCustomResourceWithCreation(package, type, name,createIfNotFound);if (rid != 0) {if (kDebugTableNoisy) {ALOGI("Pckg %s:%s/%s: 0x%08x\n",String8(package).string(), String8(type).string(),String8(name).string(), rid);}uint32_t packageId = Res_GETPACKAGE(rid) + 1;if (packageId == 0x00) {outValue->data = rid;outValue->dataType = Res_value::TYPE_DYNAMIC_REFERENCE;return true;} else if (packageId == APP_PACKAGE_ID || packageId == SYS_PACKAGE_ID || packageId == SYS_MTK_PACKAGE_ID || packageId == SYS_CUSTEMER_PACKAGE_ID) {// We accept packageId's generated as 0x01 in order to support// building the android system resourcesoutValue->data = rid;return true;}}}}DynamicRefTable::DynamicRefTable(uint8_t packageId, bool appAsLib): mAssignedPackageId(packageId), mAppAsLib(appAsLib)
{memset(mLookupTable, 0, sizeof(mLookupTable));// Reserved package idsmLookupTable[APP_PACKAGE_ID] = APP_PACKAGE_ID;mLookupTable[SYS_PACKAGE_ID] = SYS_PACKAGE_ID;mLookupTable[SYS_MTK_PACKAGE_ID] = SYS_MTK_PACKAGE_ID;mLookupTable[SYS_CUSTEMER_PACKAGE_ID] = SYS_CUSTEMER_PACKAGE_ID;
}}

SYS_CUSTEMER_PACKAGE_ID 需要对应与自定义模块mk文件的 LOCAL_AAPT_FLAGS

七、将资源apk路径添加进白名单

路径:frameworks/base/core/jni

static const char* kPathWhitelist[] = {"/dev/null","/dev/socket/zygote","/dev/socket/zygote_secondary","/system/etc/event-log-tags","/sys/kernel/debug/tracing/trace_marker","/system/framework/framework-res.apk","/dev/urandom","/dev/ion","/dev/dri/renderD129", // Fixes b/31172436"/proc/ged", // MTK add"/system/vendor/framework/mediatek-res/mediatek-res.apk", // MTK add"/system/framework/custemer-res/custemer-res.apk" /* XXX add */
};

修改的目的是为了通过开机的检查,否则无法开机。

关于如何使用,就不作记录了。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/503503.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

LabVIEW计算机软件著作权

计算机软件著作权是指软件开发者对其创作的软件作品享有的法律保护权利&#xff0c;目的是防止他人未经授权复制、修改或传播该软件。软件著作权不仅包括软件的源代码&#xff0c;还包括文档、界面设计、功能模块、程序逻辑等内容。通过登记软件著作权&#xff0c;开发者可以获…

unity学习13:gameobject的组件component以及tag, layer 归类

目录 1 gameobject component 是unity的基础 1.1 类比 1.2 为什么要这么设计&#xff1f; 2 从空物体开始 2.1 创建2个物体 2.2 给 empty gameobject添加组件 3 各种组件和新建组件 3.1 点击 add component可以添加各种组件 3.2 新建组件 3.3 组件的操作 3.4 特别的…

Vue项目中的问题汇总(持续更新中)

1.vue 循环 span 标签产生了间隙 代码如下&#xff1a; <template><div class"box"><span v-for"(item,index) in items" ::key"index">{{ item }}</span><span>修改</span><span>删除</span>…

ffmpeg7.0 合并2个 aac 文件

ffmpeg7.0 将2个aac文件合并。 #include <stdio.h>// 之所以增加__cplusplus的宏定义&#xff0c;是为了同时兼容gcc编译器和g编译器 #ifdef __cplusplus extern "C" { #endif #include <libavformat/avformat.h> #include <libavcodec/avcodec.h>…

Midjourney 应用:框架总结

Midjourney 应用&#xff1a;框架总结 官方的模板很简单&#xff0c;分成四个部分&#xff1a; 主体细节 & 背景风格、媒介、艺术家参数 我的总结 其实按照官方模板写&#xff0c;你已经能超过 90% 的初学者&#xff0c;但根据我的实验&#xff0c;我细化了他们的模板的…

JVM实战—OOM的定位和解决

1.如何对系统的OOM异常进行监控和报警 (1)最佳的解决方案 最佳的OOM监控方案就是&#xff1a;建立一套监控平台&#xff0c;比如搭建Zabbix、Open-Falcon之类的监控平台。如果有监控平台&#xff0c;就可以接入系统异常的监控和报警&#xff0c;可以设置当系统出现OOM异常&…

JVM实战—13.OOM的生产案例

大纲 1.每秒仅上百请求的系统为何会OOM(RPC超时时间设置过长导致QPS翻几倍) 2.Jetty服务器的NIO机制如何导致堆外内存溢出(S区太小 禁NIO的显式GC) 3.一次微服务架构下的RPC调用引发的OOM故障排查实践(MAT案例) 4.一次没有WHERE条件的SQL语句引发的OOM问题排查实践(使用MA…

【银河麒麟高级服务器操作系统实例】tcp半链接数溢出分析及处理全过程

了解更多银河麒麟操作系统全新产品&#xff0c;请点击访问 麒麟软件产品专区&#xff1a;https://product.kylinos.cn 开发者专区&#xff1a;https://developer.kylinos.cn 文档中心&#xff1a;https://document.kylinos.cn 服务器环境以及配置 系统环境 物理机/虚拟机/云…

visual studio 自动调整代码格式的问题:

1.取消自动调整格式 2.如果是想让代码显得更紧凑&#xff0c;上面的不动&#xff0c;按这个来&#xff1a;

javaEE-网络原理-1初识

目录 一.网络发展史 1.独立模式 2.网络互联 二.局域网LAN 1.基于网线直连&#xff1a; 2.基于集线器组件&#xff1a; 3.基于交换机组件&#xff1a; 4.基于交换机和路由器组件 ​编辑 三、广域网WAN 四、网络通信基础 1.ip地址 2.端口号&#xff1a; 3.协议 4.五…

三维卷积( 3D CNN)

三维卷积&#xff08; 3D CNN&#xff09; 1.什么是三维卷积 1.1 三维卷积简介 二维卷积是在单通道的一帧图像上进行滑窗操作&#xff0c;输入是高度H宽度W的二维矩阵。 三维卷积输入多了深度C这个维度&#xff0c;输入是高度H宽度W深度C的三维矩阵。在卷积神经网络中&…

黄仁勋演讲总结(2种显卡,1个开源大模型,1个数据采集平台)

研发算力显卡RTX50系列&#xff0c;PC端显卡GB10&#xff0c;开源大模型Cosmos&#xff08;用于机器人和自动驾驶&#xff09;&#xff0c; Isaac GR00T&#xff08;人形机器人的数据采集平台&#xff09;。 新一代 RTX 50 系列显卡 RTX 50 系列 GPU&#xff0c;相对之前系列&a…

阿尔法linux开发板ping不通百度

我使用的阿尔法linux板子&#xff0c;发现按照《03【正点原子】I.MX6U网络环境TFTP&NFS搭建手册V1.3.2》一套操作下来&#xff0c;还是没办法实现板子上网。 我总结了下面方法&#xff0c;我如何实现联网和互ping通&#xff0c;大致总结下三步 一、pc端的wifi网络&#xf…

使用图像过滤器在 C# 中执行边缘检测、平滑、浮雕等

图像过滤器可让您对图像中的像素执行操作。这是一个相当大的示例,因此您可能需要花一些时间浏览代码。 在一种图像滤镜中,您有一个称为滤镜内核的值数组。对于图像中的每个像素,您将内核置于该像素的中心。然后将内核下的每个像素的值乘以相应的内核值。将它们相加,除以“…

数值分析速成复习笔记

请确保你有10hour的有效学习时间&#xff0c;保你拿90 证明部分 编程部分

如何快速上手一个鸿蒙工程

作为一名鸿蒙程序猿&#xff0c;当你换了一家公司&#xff0c;或者被交接了一个已有的业务。前辈在找你之前十分钟写了一个他都看不懂的交接文档&#xff0c;然后把一个鸿蒙工程交接给你了&#xff0c;说以后就是你负责了。之后几天你的状态大概就是下边这样的&#xff0c;一堆…

asammdf python库解析MF4文件(一)cut and filter

目录 cutfilter asammdf 是一个功能强大的 Python 库&#xff0c;专门用于处理汽车行业常用的 MDF&#xff08;Measured Data Format&#xff09;文件 这篇文章主要介绍mdf库的cut和filter函数 cut cut函数主要用于裁剪数据&#xff0c;比如你的MF4文件是一个100s的数据&…

性能测试01|性能测试理论

目录 一、性能测试概述 二、性能测试的分类 1、基准测试 2、负载测试 3、稳定性测试 4、压力测试 5、并发测试 三、性能测试的指标 1、响应时间 2、并发用户数 3、吞吐量 4、点击数 5、错误率 6、资源利用率 四、性能测试流程 1、性能需求分析 2、性能测试计划…

基于SpringBoot的斯诺克球馆预约购票管理系统

作者&#xff1a;计算机学姐 开发技术&#xff1a;SpringBoot、SSM、Vue、MySQL、JSP、ElementUI、Python、小程序等&#xff0c;“文末源码”。 专栏推荐&#xff1a;前后端分离项目源码、SpringBoot项目源码、Vue项目源码、SSM项目源码、微信小程序源码 精品专栏&#xff1a;…

【JavaWeb】2. 通用基础代码

以下内容来源&#xff1a;编程导航。 无论在任何后端项目中&#xff0c;都可以复用的代码。 1、自定义异常 自定义错误码&#xff0c;对错误进行收敛&#xff0c;便于前端统一处理。 &#x1f4a1; 这里有 2 个小技巧&#xff1a; 自定义错误码时&#xff0c;建议跟主流的错…