如何为Android系统添加一个新的资源包

传统的Android系统只有一个framework-res.apk资源包,第三方厂商在进行rom定制时会直接修改framework res资源,达到美化目的。但是这种方式跟原生资源的耦合度过高,在系统迁移或者framework ui移植时需要进行人工merge,工作量巨大。通过为Android添加一个新的独立的资源包,可以将厂商定制资源独立出来,可移植、可维护性非常好。

具体做法可以分为以下几个步骤:

1. 修改build/core/clear_var.mk

LOCAL_USE_LETV_FRAMEWORK_RES:= true

2. 修改build/core/package.mk

以下脚本可以加在 $(R_file_stamp): $(framework_res_package_export_deps) 之前,然后修改$(R_file_stamp): $(framework_res_package_export_deps) 和 $(LOCAL_INTERMEDIATE_TARGETS): \
    PRIVATE_AAPT_INCLUDES := $(framework_res_package_export)

如下所示:

view sourceprint?
1 ifeq ($(LOCAL_USE_LETV_FRAMEWORK_RES),true) 

2 letv_framework_res_package_export := \ 

3         $(call intermediates-dir-for,APPS,letv-framework-res,,COMMON)/package-export.apk 

4 letv_framework_res_package_export_deps := \ 

5         $(dir $(letv_framework_res_package_export))src/R.stamp 

6 else 

7 letv_framework_res_package_export := 

8 letv_framework_res_package_export_deps := 

9 endif # LOCAL_USE_LETV_FRAMEWORK_RES
view sourceprint?
1 $(R_file_stamp): $(framework_res_package_export_deps) $(letv_framework_res_package_export_deps) 

2 $(LOCAL_INTERMEDIATE_TARGETS): \ 

3     PRIVATE_AAPT_INCLUDES := $(framework_res_package_export) \ 

4         $(letv_framework_res_package_export) 

5 endif # LOCAL_NO_STANDARD_LIBRARIES
3. 修改build/target/product/core.mk

在PRODUCT_PACKAGES增加letv-framework-res

4. 添加一个新的资源包项目,这里在framework/base/core/res同级目录下建立一个新的文件夹letv_res用来存放我们的资源。把res目录下的AndroidManifest.xml和Android.mk拷贝过来,进行修改。 

记得设置LOCAL_USE_MY_FRAMEWORK_RES为false。

view sourceprint?
01 LOCAL_PATH:= $(call my-dir) 

02 include $(CLEAR_VARS) 

03   

04 LOCAL_MODULE_TAGS := optional 

05   

06 LOCAL_PACKAGE_NAME := letv-framework-res 

07 LOCAL_CERTIFICATE := platform 

08   

09 # Set LOCAL_USE_LETV_FRAMEWORK_RES as false 

10 LOCAL_USE_LETV_FRAMEWORK_RES := false 

11   

12 # Tell aapt to create "extending (non-application)" resource IDs, 

13 # since these resources will be used by many apps. 

14 LOCAL_AAPT_FLAGS := -x 

15   

16 # Install this alongside the libraries. 

17 LOCAL_MODULE_PATH := $(TARGET_OUT_JAVA_LIBRARIES) 

18   

19 # Create package-export.apk, which other packages can use to get 

20 # PRODUCT-agnostic resource data like IDs and type definitions. 

21 LOCAL_EXPORT_PACKAGE_RESOURCES := true 

22   

23 # Include resources generated by system RenderScript files. 

24 framework_GENERATED_SOURCE_DIR := $(call intermediates-dir-for,JAVA_LIBRARIES,framework,,COMMON)/src 

25 framework_RenderScript_STAMP_FILE := $(framework_GENERATED_SOURCE_DIR)/RenderScript.stamp 

26 #LOCAL_RESOURCE_DIR := $(framework_GENERATED_SOURCE_DIR)/renderscript/res $(LOCAL_PATH)/res 

27   

28 include $(BUILD_PACKAGE) 

29   

30 # Make sure the system .rs files get compiled before building the package-export.apk. 

31 #$(resource_export_package): $(framework_RenderScript_STAMP_FILE) 

32   

33 # define a global intermediate target that other module may depend on. 

34 .PHONY: letv-framework-res-package-target 

35 letv-framework-res-package-target: $(LOCAL_BUILT_MODULE)



view sourceprint?
01 <?xml version="1.0" encoding="utf-8"?> 

02 <manifest xmlns:android="http://schemas.android.com/apk/res/android"

03     package="letv" coreApp="true" android:sharedUserId="android.uid.system"

04     android:sharedUserLabel="@null"> 

05   

06     <application android:process="system"

07                  android:persistent="true"

08                  android:hasCode="false"

09                  android:label="@null"

10                  android:allowClearUserData="false"

11                  android:killAfterRestore="false"

12                  android:icon="@null"> 

13   

14     </application> 

15   

16 </manifest>



资源的放置跟res下的类似,记得values目录下创建public.xml,public.xml对id的类型区分比较严格,attr必须是0x0x010000开头,drawable必须是0x0x020000开头,其他类型好像就没有限制,直接依次0x0x030000、0x0x040000开始即可。否则,编译过程中会出现segmentation fault错误。

view sourceprint?
1 <resources> 

2  <public type="attr" name="cForeground" id="0x03010000" /> 

3  <public type="drawable" name="ic_filemanager" id="0x03020000" /> 

4  <public type="style" name="LetvTheme" id="0x03030000" /> 

5  <public type="string" name="letv" id="0x03040000" /> 

6  <public type="dimen" name="letv_width" id="0x03050000" /> 

7  <public type="layout" name="letv_text" id="0x03060000" /> 

8 </resources>
5.  以上只是解决了资源的编译环境问题,资源的查找过程也需要进行修改,修改 AssetManager.java,在init()后添加代码 addAssetPath("/system/framework/letv-framework-res.apk");
view sourceprint?
01 public AssetManager() { 

02         synchronized (this) { 

03             if (DEBUG_REFS) { 

04                 mNumRefs = 0; 

05                 incRefsLocked(this.hashCode()); 

06             } 

07             init(); 

08             addAssetPath("/system/framework/letv-framework-res.apk"); 

09             if (localLOGV) Log.v(TAG, "New asset manager: " + this); 

10             ensureSystemAssets(); 

11         } 

12     }



6. 最后就是资源应用问题。应用程序在xml文件中引用letv-framework-res.apk中的资源时可以使用与原生资源类似的访问方式,首先声明letv xmlns :

view sourceprint?
1 xmlns:letv="http://schemas.android.com/apk/res/letv"
然后像@android:drawable @android:dimen这种引用方式改成@letv:drawable @letv:dimen即可。

view sourceprint?
01 <?xml version="1.0" encoding="utf-8"?> 

02 <LinearLayout

03     xmlns:android="http://schemas.android.com/apk/res/android"

04     xmlns:letv="http://schemas.android.com/apk/res/letv"

05     android:layout_width="fill_parent"

06     android:layout_height="wrap_content"

07     android:gravity="center"

08     android:paddingTop="@letv:dimen/letv_width"

09     android:orientation="horizontal" > 

10   

11    <ImageView android:id="@+id/file_icon"

12             android:layout_width="wrap_content"

13             android:layout_height="wrap_content"

14             android:layout_gravity="center"

15             android:layout_marginBottom="40dp"

16             android:src="@letv:drawable/ic_filemanager" /> 

17   

18 </LinearLayout>

猜你喜欢

转载自sunj.iteye.com/blog/2002370
今日推荐