多目标
有时候多个应用使用了相同的资源,为了方便定制资源包的管理,需要一个定制资源包可以同时覆盖对多个目标应用。
但是相同资源在每个应用中的资源名称定义的一般都不一样,这就需要我们对Android的ID映射(idmap)机制进行扩展,引入名称映射(name-map)机制。
定制资源包里面应该针对每一个覆盖目标,包含一个“名称映射”描述文件。
为了兼容只有ID映射的情形,可以规定如果针对某个覆盖目标,没有对应的名称映射文件,那么仅使用ID映射。
多目标的定制资源包在加载时,只加载一份。
包依赖
因为基础资源包中存在依赖关系(插件依赖,定制交互依赖),所以定制资源包也应该存在依赖关系。
依赖场景:当定制交互需要使用儿童风格的皮肤资源,需要同时切换标准交互的皮肤资源。此时定制交互的儿童风格皮肤资源包依赖标准交互的儿童风格皮肤资源包。
定制资源的依赖计算和应用:因为资源包依赖和覆盖都是多元的,导致情况比较复杂。基本思路是:
- 定制资源包和基础资源包的依赖关系分开处理
- 定制资源包的依赖包含自己(因为可能多目标),并排在第一位
- 按一定的次序遍历定制资源的依赖关系(比如广度优先)(依赖不可以循环)
- 遍历时,收集覆盖关系,以覆盖目标为Key,对同一个目标的多个覆盖是有序的
- 只覆盖有依赖关系的基础资源包,覆盖时不再递归上述计算,而是直接使用已经收集到的覆盖关系
资源包细节
- 插件声明
定制资源包天然是一种插件,采样插件描述方案来描述。
定制资源包与普通插件唯一的区别在于:其资源描述中多了“overlays”一项。
插件相关描述清单:
项目 |
意义 |
备注 |
overlays |
覆盖目标 |
覆盖的基础资源包,多项 |
- 插件描述(res/xml/plugin.xml)
<?xml version="1.0" encoding="utf-8"?>
<plugin xmlns:android="http://schemas.android.com/apk/res/android" …… overlays="@array/skin_overlays /> |
注意:为防止插件描述相关的资源覆盖,皮肤包中这类资源的名称需要特殊,比如用skin开头。
名称映射文件
名称映射是一个raw格式的资源,针对每个覆盖的目标资源包,有一个名称映射文件。如果没有对应的名称映射文件,则对该目标资源包的覆盖采用idmap默认行为。
文件名:
target-package-name.namemap
文本内容定义格式为:
[type1] overlay-name1:target-name1 overlay-name2:target-name2 [type2] …… |