日本不卡不码高清免费观看,久久国产精品久久w女人spa,黄色aa久久,三上悠亚国产精品一区二区三区

您的位置:首頁技術文章
文章詳情頁

Android 解決游戲發行切包資源索引沖突的問題

瀏覽:146日期:2022-09-20 15:49:08
背景

游戲發行切包過程中,經常碰到渠道、研發、發行方,三方資源在合并過程中,資源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了,那么打包資源時就用已經有的id。

3、public.xml中的id的格式

共四個字節32位,第一個字節代表PackgeID,第二個字節代表TypeID,后兩個字節代表資源值

通常系統資源PackageID是01,而我們自己的資源PackageID是7f

TypeID,比如attr為01,string為02。但是并不固定,并不一定attr就是01。但是在public.xml中,同類型的該字節一定是一樣的,否則回編譯會失敗。

2、R類介紹

R類這里有個知識點,library模塊中生成的R類中的成員的值不是常量,不帶final。app模塊生成的R類的值是常量值。而常量值在java編譯時會被優化,最終代碼中輸出的就是常量值,而不是R.id.xxx這樣。而library的因為是變量,不會被優化,代碼中會保留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建立的是app工程,R類是常量值,如果我們把母包中public.xml中已有的值給改了,萬一母包中用了,那就gg了

由于R類在library中使用的時候是個變量,保留了R.id.xxx這種形式,解決方法就有了,糾正R類中的值跟public.xml對應,這樣就能繼續愉快的使用R.id.xxx了。

我們的切包過程有幾個步驟:

反編譯母包(指接入我們SDK的乙方)====》合并渠道資源====》合并入新sdk的資源(跳過研發更新我們的sdk的過程哈)

1、在反編譯母包的時候解析public.xml的值,存下來。

private void init() { List<Element> elements = mDocument.getRootElement().elements(); for (Element element : elements) { String type = element.attribute(TYPE).getStringValue(); String name = element.attribute(NAME).getStringValue(); String id = element.attribute(ID).getStringValue(); Map<String, String> typeMap = mTypeMap.get(type); if (typeMap == null) { typeMap = new HashMap<>(); typeMap.put(name, id); mTypeMap.put(type, typeMap); } else { typeMap.put(name, id); } }}2、合并渠道資源的時候,將渠道資源中的public.xml(以channelPublic代指)合并到母包的public.xml(以matrixPublic代指)中

合并策略:

a、channelPublic中有,而matrixPublic中沒有,增加到matrixPublic中

比如增加如下數據到matrixPublic中

<public type='attr' name='iconSrc' />

如果該type在matrixPublic中已經存在:

首先要獲取到attr在matrixPublic中的PackageId+TypeId。在一個public.xml文件中,同類型比如attr對應的PackageId+TypeId是不能變的,否則回編譯失敗。因此要添加數據時,數據的PackageId+TypeId需要糾正為matrixPublic的值。

其次資源值,不能和已有的資源值重復,正常情況下public.xml中的值是aapt生成的有序的,這里可以掃描matrixPublic中attr類型值的最大值,然后加一作為新加的iconSrc的id值

如果該type在matrixPublic中不存在(假設母包中matrixPublic中不存在attr類型)

首先要獲取類型已經被占用的有哪些,即獲取到matrixPublic中的TypeId,正常情況也是有序的,獲取出最大的TypeId,加一作為新Type的起始值。賦值給iconSrc的id值

b、channelPublic中有,而matrixPublic中也有的,不需要處理,保留matrixPublic中的值不變

3、合并入新sdk的資源,在覆蓋完R類,后開始糾正R類的值

掃描R類在PublicAndRHelper中

掃描覆蓋完R類的smali代碼中所有的R類,R$styleable類除外,因為styleable中保存的是一些數組的值,規則不同。

/** * 掃描代碼中的R類 * @return */ private void scannerRClass(String path) { File smaliFilePath = new File(path); for (File file : smaliFilePath.listFiles()) { if (file.isDirectory()) { scannerRClass(file.getAbsolutePath()); } else if(file.isFile()){ if (file.getName().equals('R.smali') || file.getName().startsWith('R$')) { //此處過濾掉styleable文件 if (!file.getName().endsWith('R$styleable.smali')) { mRClassFileList.add(file.getAbsolutePath()); } } } } }

針對每一個R類調用糾正R類中方法,糾正R類值在RValueHelper類中

策略:匹配出要糾正的行,獲取到type,name。在public.xml中找出對應的值,糾正。

注意這里的糾正不要用replace(oldValue,newValue)這種方式,要用替換行的方式,因為存在新值在R類中也存在后,后續替換出問題。比如a替換成b,b替換成c的情況最終R類中的a和b都被替換成了c

其次是styleable的處理,當掃描到的R是attr類型的時候,判斷是否有styleable類型的存在,如果存在,則緩存下來attr中所做的糾正,用于糾正styleable。

public static void handle(String RFilePath, PublicXmlBean publicXmlBean) { File RFile = new File(RFilePath); String RStyleFilePath = ''; Map<String, String> cacheMap = null; if (RFile.getName().endsWith('R$attr.smali')) { RStyleFilePath = RFilePath.replace('R$attr', 'R$styleable'); File RStyleAbleFile = new File(RStyleFilePath); //styleable存在,則把attr文件替換過的值緩存 if (RStyleAbleFile.exists()) { cacheMap = new HashMap<>(); } } String rFileContent = FileUtil.read(RFilePath); //找到RFile中是屬性的每一行 ArrayList<String> lines = FileUtil.readAllLines(RFilePath, '.field public static final'); String regex = '.field public static final (.*):(.*) = (.*)'; for (String line : lines) { Pattern pattern = Pattern.compile(regex); Matcher matcher = pattern.matcher(line); if (matcher.find()) { String type = RFile.getName().replace('R$', '').replace('.smali', ''); String name = matcher.group(1); String resetValue = publicXmlBean.getValue(type, name); if (StringUtils.isEmpty(resetValue)) { resetValue = publicXmlBean.addValue(type, matcher.group(1)); } //替換到文件內容中 rFileContent = rFileContent.replace(line, '.field public static final ' + name + ':' + matcher.group(2) + ' = ' + resetValue); if (cacheMap != null) { //換過的值緩存起來 cacheMap.put(matcher.group(3), resetValue); } } } FileUtil.write(RFilePath, rFileContent); if (cacheMap != null) { //糾正R$styleable的值 List<String> styleAbleLines = FileUtil.readAllLines(RStyleFilePath); BufferedWriter bw = null; try { bw = new BufferedWriter(new FileWriter(RStyleFilePath)); for (String styleAbleLine : styleAbleLines) { for (String key : cacheMap.keySet()) { if (styleAbleLine.contains(key)) { styleAbleLine = styleAbleLine.replace(key, cacheMap.get(key)); } } bw.write(styleAbleLine); bw.newLine(); } } catch (IOException e) { e.printStackTrace(); } finally { if (bw != null) { try { bw.close(); } catch (IOException e) { bw = null; } } } } }

至此,糾正完了R類和public.xml的值

4、小結

游戲發行行業中,切包過程由于是多方代碼資源的一個合并過程,經常出現資源沖突問題。本方案致力于優化切包過程,自動化地解決資源沖突問題。本方案已申請專利,并在我們實際業務中使用并穩定運行

以上就是Android 解決游戲發行切包資源索引沖突的問題的詳細內容,更多關于Android 游戲發行切包資源索引沖突的資料請關注好吧啦網其它相關文章!

標簽: Android
相關文章:
日本不卡不码高清免费观看,久久国产精品久久w女人spa,黄色aa久久,三上悠亚国产精品一区二区三区
日韩激情中文字幕| 国产一区二区三区四区五区| 欧美精品日日操| 国产成人调教视频在线观看| 麻豆中文一区二区| 精品国产三区在线| 福利一区和二区| 日韩国产专区| 久久九九精品| 久久麻豆精品| 国产精品一区2区3区| 欧美影院三区| 99久久精品国产亚洲精品| 青青青国产精品| 亚洲色诱最新| 欧美日韩va| 伊人久久成人| 亚洲欧美视频一区二区三区| 免费在线观看成人| 日韩精品亚洲专区| 国产一区二区三区天码| 1000部精品久久久久久久久| 久久精品999| 欧美韩一区二区| 亚洲一本视频| 麻豆传媒一区二区三区| 蜜臀91精品国产高清在线观看| 午夜电影一区| 99成人超碰| 蜜桃tv一区二区三区| 久久99国产精品视频| 国产中文欧美日韩在线| 欧美日韩免费看片| 蜜臀精品久久久久久蜜臀| 欧美日韩 国产精品| 久热re这里精品视频在线6| 天堂√中文最新版在线| 亚洲尤物av| 久久久久久久久久久妇女| 久久狠狠婷婷| 深夜福利一区| 视频在线不卡免费观看| 免费在线日韩av| 国产一区二区三区免费在线| 亚洲女同中文字幕| 国产日本久久| 久久九九国产| 九九精品调教| 亚洲欧美久久久| 国产精品xvideos88| 国产精品亚洲一区二区三区在线观看| 精品中文字幕一区二区三区四区| 久久一区精品| 欧美日韩精品一本二本三本| 婷婷综合网站| 综合激情网站| 青草国产精品久久久久久| 国产精品任我爽爆在线播放 | 国产精品久久久久9999高清| 日本不卡视频一二三区| 亚洲精选91| 精品无人区麻豆乱码久久久| 日韩和欧美一区二区三区| 欧美激情网址| 亚洲视频www| 精品国产乱码| 国产高清视频一区二区| 国产日韩欧美一区二区三区| 亚洲性色av| 国产日韩视频| 国产美女精品| 日韩精品中文字幕第1页| 日韩高清不卡一区| 亚洲精品91| 亚洲深深色噜噜狠狠爱网站| 精品久久久久中文字幕小说| 免费久久精品视频| 欧美成a人国产精品高清乱码在线观看片在线观看久 | 自由日本语亚洲人高潮| 精品高清久久| 国产精品久久久久久久久久10秀 | 亚洲毛片在线免费| 91精品福利观看| 亚洲欧美日韩高清在线| 91欧美在线| 国产丝袜一区| 美女精品在线| 久久精品国产亚洲夜色av网站 | 日韩另类视频| 亚洲精品看片| 成人福利一区 | 国产suv精品一区二区四区视频| av一区在线| 麻豆精品网站| 国产精品久久久一区二区| 中文字幕成人| 成人国产精选| 一本综合精品| 午夜国产精品视频| 黄色在线网站噜噜噜| 午夜久久久久| 日韩精品亚洲一区二区三区免费| 欧美啪啪一区| 蜜桃伊人久久| 1000部精品久久久久久久久| 三级亚洲高清视频| 青青草91久久久久久久久| 日韩午夜黄色| 国产精品主播在线观看| 丝袜脚交一区二区| 久久久国产精品网站| 精品国产乱码久久久久久1区2匹| 国产+成+人+亚洲欧洲在线| 日韩国产在线一| 福利片在线一区二区| 国产精品红桃| 国产精品久久国产愉拍| 欧美日本不卡高清| 国产精品资源| 久久av影院| 亚洲精品一区二区在线看| 日韩久久精品| 欧产日产国产精品视频| 日韩福利视频一区| 国产精品字幕| 亚洲精选成人| 亚洲伊人精品酒店| 亚洲欧美不卡| 尤物tv在线精品| 啪啪国产精品| 精品视频在线你懂得| 日韩毛片一区| 亚洲一区黄色| 蜜桃视频一区二区三区 | 国产日韩一区二区三免费高清 | 先锋亚洲精品| 午夜一区在线| 国产三级一区| 亚洲精品三级| 亚洲精品极品| 自由日本语亚洲人高潮| 69精品国产久热在线观看| 日本综合视频| 欧美亚洲一区二区三区| 美女精品久久| 日韩一区网站| 久久精品国语| 欧美日韩一视频区二区| 久久国产精品免费一区二区三区 | 三上悠亚国产精品一区二区三区 | 日韩精品欧美精品| 国产精品久久久久久久久久白浆 | 精品久久久网| 蜜桃久久久久久久| 日本一二区不卡| 偷拍精品精品一区二区三区| 欧美视频久久| 视频一区二区不卡| 亚洲欧美日韩在线观看a三区| 日韩一级精品| 国产精品香蕉| 神马久久午夜| 美女精品久久| 91国内精品| 婷婷精品在线| 色婷婷成人网| 久久大逼视频| 青青草国产成人99久久| 日韩国产一区| 久久精品xxxxx| 亚洲欧美视频一区二区三区| 亚洲精品高潮| 国内精品美女在线观看| 黄色精品网站| 欧美va天堂在线| 在线精品一区二区| 美女黄网久久| 欧美亚洲三区| 日韩欧美中文在线观看| 国产精品成人国产| 日韩一区三区| 亚洲欧美在线综合| 丁香婷婷久久| 免费在线观看日韩欧美| 精品国产黄a∨片高清在线| 亚洲精品91| 99视频精品全部免费在线视频| 久久精品五月| 韩日一区二区三区| 日韩高清在线不卡| 久久国产欧美| 免费成人网www| 日本精品一区二区三区在线观看视频| 91亚洲国产高清| 综合国产视频| 亚洲欧洲美洲国产香蕉| 亚洲免费资源| 亚洲ww精品| 日韩二区在线观看| 日本不卡免费高清视频在线|