关于游戏SDK,l合并的那些事
关于sdk的那点事,多次在sdk看到同⾏讨论R⽂件。所以写出我的思路,分享⼀下⾃⼰的经验。
那么开始吧,
⾸先⼀般发现需要做合并R操作的, 基本上都是遇到了,没有使⽤”⾏规“, 动态获取资源id,⽽是使⽤R.id的⽅式
在说明前, 先暂且称 原母包为A包,需要替换的资源包为B包 , 并且需知道 l是⽤来固定资源id的
那么就有
⽅式⼀ 同时删除 A与B的 l 资源ID 由AAPT重新⽣成
⽅式⼆ 保留A的 l , 删除B的 l 即 B的资源id由aapt重新⽣成
⽅式三 保留B的 l ,删除A的 l 即 A的资源id由aapt重新⽣成
⽅式四 通过脚本合成 A和B的 l ,并反向修改相关的R.smali⽂件
然后A和B 获取资源的⽅式组成有
A和B都使⽤动态获取资源Id, 上诉4中⽅法都可以
A使⽤动态获取资源id,B 使⽤R.id的⽅式 ⽅法三,四 可以轻松解决
sdkA使⽤R.id,B使⽤动态获取, ⽅法⼆,四 轻松解决
A和B都使⽤R.id , ⽅法四 轻松秒杀
由上⾯分析, 基本可以得出 ⽅法四是个万⾦油的⽅法, ⽽且根据描述的理解起来也并不困难,但很多同学到了怎么合并就开始犯愁了,因为⼿头上拥有的打包脚本并没有做这⽅⾯的处理
在做合并前,需要先了解⼀下
1、l的作⽤
2、资源 ID
可以得出,
1、l是⽤来固定资源Id的
2、在构建时,aapt ⼯具会收集您定义的所有资源(尽管是单独的⽂件或⽂件中的显式定义)并为它们分配资源 ID。
资源 ID 是⼀个 32 位数字,格式为:PPTTNNNN。PP 是资源⽤于的包;TT 是资源的类型;NNNN 是该类型中资源的名称。对于应⽤程序资源,PP 始终为 0x7f
TT 和 NNNN 值由 aapt 任意分配——基本上对于每种新类型,都会分配和使⽤下⼀个可⽤数字(从 1 开始);同样,对于类型中的每个新名称,都会分配和使⽤下⼀个可⽤编号(从 1 开始)。
拥有上⾯的知识后,基本上合并l也就并没有难度了
逻辑可以参考如下
因为PP始终为0x7f
value = TTNNNN , 资源id为 0x7f + value
可以这么表⽰ [type][name] = value
那么,我们合并逻辑就可以是, ⽤A包作为母本,B包融合进A包
即 A的l 先固定
然后从B包的l ⾥⾯把每个资源id 拿出出来
先判断是否有type, 再判断是否有name 若[type][name] 存在就跳过,若name不存在,就拿type的maxid + 1 python代码如下
def public_merged(self):
plug_value_path = os.path.join(self._plug_path, "handleres", "values")
plug_public_file_path = os.path.join(plug_value_path, "l")
with open(plug_public_file_path, 'r') as xml_file:
plug_public_xml = ET.parse(xml_file)
package_public_file_path = os.path.join(self._package_path, "res", "values", "l")
with open(package_public_file_path, 'r') as xml_file:
package_xml = ET.parse(xml_file)
package_unique_id_mapping = {}
for ele in t():
id_type = ele.attrib['type']
id_name = ele.attrib['name']
id_value = int(ele.attrib['id'], 16)
if id_type not in package_unique_id_mapping:
package_unique_id_mapping[id_type] = {}
package_unique_id_mapping[id_type]["maxId"] = 0
package_unique_id_mapping[id_type]["nameList"] = []
package_unique_id_mapping[id_type]["nameList"].append(id_name)
if id_value > package_unique_id_mapping[id_type]["maxId"]:
package_unique_id_mapping[id_type]["maxId"] = id_value
all_type_max_id = 0
for type_map in package_unique_id_mapping.values():
if type_map["maxId"] > all_type_max_id:
all_type_max_id = type_map["maxId"]
for ele in plug_t():
id_type = ele.attrib['type']
id_name = ele.attrib['name']
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论