1、新建资源项目,如mediatek,目录结构:(和其他app一样,因为只要资源,不需要src)
目录存放到framework/base/core/mediatek
Android.mk
AndroidManifest.xml
2、.Android.mk内容:
include $(CLEAR_VARS)
LOCAL_PACKAGE_NAME := mediatek-res
LOCAL_CERTIFICATE := platform
# Tell aapt to create “extending (non-application)” resource IDs,
# since these resources will be used by many apps.
LOCAL_AAPT_FLAGS := -x
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
LOCAL_BUILDING_ITFUN_RES := true
include $(BUILD_PACKAGE)
# define a global intermediate target that other module may depend on.
.PHONY: mediatek-res-package-target
mediatek-res-package-target: $(LOCAL_BUILT_MODULE)
3.AndroidManifest.xml写法与app一样,这里的包名为package="mediatek" android:sharedUserId="android.uid.system"
4.修改build/core下package.mk文件
1) 找到resource_export_package := $(intermediates.COMMON)/package-export.apk 行下方添加:# ITFUN change begin: ensure framework-res is built before building mediatek-resifeq ($(LOCAL_BUILDING_ITFUN_RES), true)$(resource_export_package): $(call intermediates-dir-for,APPS,framework-res,,COMMON)/src/R.stampendif# ITFUN change end: ensure framework-res is built before building mediatek-res2) 找到 else # LOCAL_SDK_VERSION 行
下方添加:
# ITFUN change begin: ensure itfun-res is linked as dependency
ifeq ($(LOCAL_BUILDING_ITFUN_RES), true)
itfun_res_package_export :=
itfun_res_package_export_deps :=
else
itfun_res_package_export := \ $(call intermediates-dir-for,APPS,mediatek-res,,COMMON)/package-export.apk itfun_res_package_export_deps := \ $(dir $(mediatek_res_package_export))src/R.stamp endif # INTUN change end
5、修改framework/base 下Android.mk 文件
framework_res_source_path := APPS/framework-res_intermediates/src#***************************************************************# add other-framework-res mediatek_res_source_path := APPS/mediatek-res_intermediates/srcLOCAL_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 \ $(mediatek_res_source_path)/mediatek/R.java \ $(mediatek_res_source_path)/mediatek/Manifest.java \ $(mediatek_res_source_path)/com/mediatek/internal/R.java# 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.stampmediatek_res_R_stamp := \ $(call intermediates-dir-for,APPS,mediatek-res,,COMMON)/src/R.stamp $(full_classes_compiled_jar): $(framework_res_R_stamp) $(mediatek_res_R_stamp)# Make sure that framework-res is installed when framework is.$(LOCAL_INSTALLED_MODULE): | $(dir $(dir $(LOCAL_INSTALLED_MODULE))mediatek-res.apk)framework-res.apk4、修改frameworks/base/libs/utils/AssertManage.cpp文件
a 找到static const char* kSystemAssets = "framework/framework-res.apk";行
下方添加static const char* kItfunAssets = "framework/mediatek-res.apk";b addDefaultAssets 函数改为:
bool AssetManager::addDefaultAssets(){ const char* root = getenv("ANDROID_ROOT"); LOG_ALWAYS_FATAL_IF(root == NULL, "ANDROID_ROOT not set"); String8 path(root); path.appendPath(kSystemAssets); if(!addAssetPath(path, NULL)) { return false; } String8 path2(root); path2.appendPath(kItfunAssets); return addAssetPath(path2, NULL);}
5、修改frameworks/base/services/java/com/android/server/PackageManagerService.java文件
找到libFiles.add(mFrameworkDir.getPath() + "/framework-res.apk");行
下方添加
libFiles.add(mFrameworkDir.getPath() + "/mediatek-res.apk");
6、最后make clobber 重新make ,完成后只需在代码里使用 mediatek.R.XX就可以调用了
7.如果需要在layout文件夹的xml中通过@mediatek:drawable/bg来引用资源的话,需要修改aapt工具,aapt工具有参数来-I来指定当前编译的模块的所依赖的其他模块资源,为了能够实现全编译成功,应该给make命令时,默认加上-I ***,所以这里采用修改源码的方式实现;
首先找到aapt的源码:framework/base/tools/aapt修改Main.cpp文件:
添加常量如下:static char *mm = "源码目录/out/target/common/obj/APPS/mediatek-res_intermediates/package-export.apk";char *mediatek_res = "frameworks/base/core/mediatek/res";int flag = 0;
在case ‘I’中,末尾添加if(flag){ convertPath(mm); bundle.addPackageInclude(mm);}
在case ‘S’中,末尾添加flag = strcmp(argv[0],mediatek_res);
总结:这样的话,就可以实现资源分离,不仅可以在代码中通过R.drawable.bg引用,也可以在xml文件中通过@mediatek:drawable/bg
注意:如果发现全编译时通不过,报错的话,需要在所报错的模块的mk文件中添加LOCAL_BUILDING_ITFUN_RES=true
Mokee基本就是按照这个来做的
文章来源:1