手游SDK打包问题记录

Assets目录及apktool.yml

1. assets目录的资源缺失

当打包将.jar转化为smail的时候要将源码进行转化,还要处理资源文件,所将jar里面的非class资源抽出来处理。

2. unknown目录的生成

在jar包里除了assets资源外,还可能会有其他文件比如文本文件 *.txt 等.
查看apk信息和反编译后的apk文件,可以看到对应关系。

upload successful

以上,需要在 apktool.yml文件中写入复制到unknow 文件夹的信息

3. !!brut.androlib.meta.MetaInfo

不同版本apktool工具发现打包工具用的是2.3.3版本的,但是电脑配置环境变量apktool版本是2.0.1的版本,然后手动回编译时,老是报错:“could not determine a constructor for the tag ‘tag:yaml.org,2002:brut.androlib.meta.MetaInfo’”。才发现高版本的的apktool工具在生成apktool.yml文件时,自动在第一行上添加了这个字段,再用版本回编译的时候报错。如果反编译和回编译用的版本都是一样的就没有这个问题。

4. brut.androlib.AndrolibException: brut.common.BrutException: could not exec

游戏包体资源放到assets目录太多,在回编译成apk包体时,无法编译。在apktool.yml处理下doNotCompress 字段下的字符串数字限制导致的(windows 命令行支持的字符串长度有限制,不超过8191个字符)。

为兼容apktool版本,在回编译时修改设置过滤规则修改apktool.yml文件下的doNotCompress字段。

5. libs目录合并

保证渠道提供的.so资源文件在游戏包体对应的armeabi/armeabi-v7a/x86等目录下都保持一致。不然会导致部分机型crash

6. res目录合并

渠道提供的资源目录结构与游戏反编译后的目录结构不一致问题。通常在新建安卓工程的时候,res目录的资源包大多是drawable、drawable-hdpi、drawable-xhdpi、values、values-hdpi等形式。但是反编译之后你就发现游戏的目录格式不一样:

如果游戏资源已经存在了资源文件,当拷贝渠道的资源后,回编译时,会提示资源重复,为了处理这个问题,在合并资源文件的时候,就需提前判断反编译后的目录结构。拷贝到对应的资源文件中。

7. res目录下values目录下arrays.xml/colors.xml/demens.xml/strings.xml资源丢失

拷贝完渠道res资源之后,渠道的资源同名资源会覆盖掉游戏反编译后原有的资源来保证资源是渠道的最新版本,但是需要注意的是values目录下arrays.xml/colors.xml/demens.xml/strings.xml的资源丢失问题,因为游戏apk包反编译后的资源信息都打包到这几个文件里面了,覆盖后,找不到对应的资源会导致各种问题,所以需要针对这几个资源文件做合并处理。

8. 坑点三:res目录下values/values-hdpi等目录下values.xml、values-hdpi.xml等资源冲突

个别渠道的res/values目录下提供的是values.xml、values-hdpi.xml的复合资源文件,将资源属性都定义到里面,values.xml准确来说就是arrays.xml/colors.xml/demens.xml/strings.xml等的结合体:

其实在处理arrays.xml/colors.xml/demens.xml/strings.xml资源的时候,并没有处理掉values.xml资源,后面在生成R文件的时候就会提示资源冲突了。需要先将values.xml转化为arrays.xml/colors.xml/demens.xml/strings.xml等文件。

9. 坑点四:Error parsing XML: duplicate attribute 资源属性名称重复定义

res目录下values/values-hdpi等目录下,渠道的资源属性和游戏的资源属性重复定义,比如,游戏已定义了app_name这个字段,但是渠道资源里面也定义了这个字段。这类的处理是将渠道定义的属性去掉。

10. apktool无法识别compileSdkVersion 、compileSdkVersionCodename

在实际操作过程中发现个别游戏包体反编译后,Manifest文件中有compileSdkVersion 、compileSdkVersionCodename这两个字段,即使下载了最新版本的apktool工具也无法识别。这个是因为游戏编译生成apk包时设置编译版本为compileSdkVersion = 28 才会生成的。这里需要额外处理下将compileSdkVersion 、compileSdkVersionCodename字段去掉。

但是在个别包体发现,单单去掉还不行,需将targetSdkVersion设置为23以上才不会异常。

11. aapt停止运行

一般是资源文件或是xml文件中有错误造成的。比如: 发现在反编译包体后,生成的资源文件有问题,发现在布局xml中都自动生成了n1这个字段。

最终定位的原因是模拟游戏母包的apk包是Android Studio3.0 Build Apks 生成包体,classpath ‘com.android.tools.build:gradle:3.0.0’ 生成的包体反编译后都会这样,可以通过将gradle版本设置:classpath ‘com.android.tools.build:gradle:2.3.3’ 就没有该问题出现

12. 第三方库通过R.xxx引用资源导致资源找不到问题。

这个问题很典型的案例就是个别第三方渠道引用了v7库,v7库里面的res资源是通过R.xxx引用的。在最终打出来的包体资源只会跟当前包名有关,为解决类似这种需要指定包名的问题,可以生成多个R文件的思路解决。

PS:这里有个点:生成的R文件除了包名不一致外,资源的ID都是一样的。不知道会不会有问题。

12. xml.etree import ElementTree as ET 解析xml文件出现 ns0:xxx错误

在解析文件之前需将在parse前一定要设置namespace,类似Manifest需添加下面代码。

1
ET.register_namespace('android', "http://schemas.android.com/apk/res/android")