Android如何解决游戏发行切包资源索引冲突的问题

  介绍

本篇内容介绍了“Android如何解决游戏发行切包资源索引冲突的问题”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!

背景

游戏发行切包过程中,经常碰到渠道,研发,发行方,三方资源在合并过程中,资源ID冲突导致程序异常的问题,此类问题通过getIdentifier方式规避或者修改冲突资源ID的方式可以处理,但成本较高,本文旨在提出一种在切包过程中自动化处理资源冲突的解决方案

1, public.xml介绍

1, public.xml这个文件是哪来的?

该文件是apktool在反编译apk时,根据apk包中的resources.arsc文件生成。

没看过resource.arsc吗?(自己拖个apk到IDE看吧)

2, public.xml有什么作用

publc.xml是aapt在打包资源时用来固定资源id的,如果资源在public.xml中有对应的身份了,那么打包资源时就用已经有的id。

3, public.xml中的id的格式

共四个字节32位,第一个字节代表PackgeID,第二个字节代表类型id,后两个字节代表资源值

通常系统资源PackageID是01,而我们自己的资源PackageID是7 f

类型id,比如attr为01,字符串为02。但是并不固定,并不一定attr就是01。但是在public.xml中,同类型的该字节一定是一样的,否则回编译会失败。

2 R类介绍

R类这里有个知识点,图书馆模块中生成的R类中的成员的值不是常量,不带final.app模块生成的R类的值是常量值。而常量值在java编译时会被优化,最终代码中输出的就是常量的值,而不是R.id.xxx这样。而图书馆的因为是变量,不会被优化,代码中会保留R.id.xxx

R类和public.xml的关系

从本质上讲,其实并没有啥关系。但是由于在代码中我们会使用R.id去查找资源,这就关联上了。如果都用getIdentifier的方式先获取id,那把R类删了也没事。

public.xml打包后对应的就是resources.arsc中的值,而资源值生成java类,这个类就是R类。也就是说平时使用R类,就是用里面的索引值去到resources.arsc中找到对应资源位置,再去加载。

3,切包融合过程中R类和public.xml的处理

切包过程中,R类属于代码,采用直接覆盖的方式,但是由于我们生成的R类跟母包的R类其实值会是不同的。

下文中的cp指游戏研发方,即我们的SDK的接入方。

而public.xml是用的cp的,为什么用cp的?因为cp建立的是软件工程,R类是常量的值,如果我们把母包中public.xml中已有的值给改了,万一母包中用了,那就gg了

由于R类在图书馆中使用的时候是个变量,保留了R.id.xxx这种形式,解决方法就有了,纠正R类中的值跟public.xml对应,这样就能继续愉快的使用R.id.xxx了。

我们的切包过程有几个步骤:

反编译母包(指接入我们SDK的乙方)====泛喜⑶雷试?===泛喜⑷胄耂DK的资源(跳过研发更新我们的SDK的过程哈)

1,在反编译母包的时候解析。xml的值,存下来。

private  void  init (), {   List<才能;Element>, elements =, mDocument.getRootElement . elements () ();   for 才能;(Element  Element :元素),{   ,,String  type =, element.attribute(类型).getStringValue ();   ,,String  name =, element.attribute(名字).getStringValue ();   ,,String  id =, element.attribute (ID) .getStringValue ();   ,,Map<字符串,String>, typeMap =, mTypeMap.get(类型);   ,,if  (typeMap ==, null), {   ,,,typeMap =, new  HashMap<在();   ,,,typeMap.put(名称、,id);   ,,,mTypeMap.put(类型,typeMap);   ,,},{else    ,,,typeMap.put(名称、,id);   ,,}   ,,}   }

2,合并渠道资源的时候,将渠道资源中的public.xml(以channelPublic代指)合并到母包的public.xml(以matrixPublic代指)中

合并策略:

, channelPublic中有,而matrixPublic中没有,增加到matrixPublic中

比如增加如下数据到matrixPublic中

& lt; public 类型=癮ttr", name=癷conSrc", id=? x7f0200a8",/在

如果该类型在matrixPublic中已经存在:

首先要获取到attr在matrixPublic中的PackageId +类型id。在一个public.xml文件中,同类型比如attr对应的PackageId +类型id是不能变的,否则回编译失败。因此要添加数据时,数据的PackageId + TypeId需要纠正为matrixPublic的值。

其次资源值,不能和已有的资源值重复,正常情况下。xml中的值是aapt生成的有序的,这里可以扫描matrixPublic中attr类型值的最大值,然后加一作为新加的iconSrc的id值

Android如何解决游戏发行切包资源索引冲突的问题