一、集成友盟统计
在实际项目开发过程中,由于运营的需要,我们往往需要知道我们的APP在各大应用市场的下载和具体使用情况,这时候我们往往需要接入第三方统计,较常用的就是友盟统计。具体接入方式可以查看友盟统计的官方接入文档:
- 基础组建集成:https://developer.umeng.com/docs/66632/detail/66890
- U-App统计集成:https://developer.umeng.com/docs/66632/detail/66889
仔细观察文档可以发现,在旧版本中,我们是通过在AndroidManifest.xml
文件中配置
<meta-data android:value="YOUR_APP_KEY" android:name="UMENG_APPKEY"/>
<meta-data android:value="Channel ID" android:name="UMENG_CHANNEL"/>
来实现渠道号的设置的,然后每次打新渠道包的时候,只需要手动修改这个Channel ID
即可,当然,为了减少这种手动输入,我们可以通过productFlavor
来实现多渠道打包,但这本质上还是每次都重新打一个包,只是解放了我们的双手,但并没有解决打包效率低、耗时的问题。其实我们需要的就是把我们要统计的App的渠道ID传给友盟,来让友盟进行渠道的统计,对此,友盟提供了新的接入方式:
UMConfigure.init(Context context, String appkey, String channel, int deviceType, String pushSecret)
这时候我们可以将之前AndroidManifest.xml
中的channelId
配置相关的<meta-data>
删除,只需要提供channel即可,然后就可以通过美团Walle或者其他方式来获取到这个channel即可。
二、接入美团多渠道打包方案Walle
传统打包方案除了通过productFlavor方式外,还要通过apktools方式逆向来实现多渠道,这种方式原理也很简单,就是讲apk解压,然后通过修改AndroidManifest.xml中的渠道值,再重新进行打包和签名。这种方式我们每次打包时不再需要重新构建项目。只需先打包生成一个apk,然后在该apk的基础上生成其他渠道包即可。这种方式虽然比之前快了很多,但还能更快。
美团第一代多渠道打包方式提供了在META-INF
目录内添加空文件这种方案,具体可以参考:https://tech.meituan.com/mt-a...,这种方案快在,我们能直接修改apk的渠道号,而不需要再重新签名,这样能节省不少打包的时间。据美团将,这种打包方式速度非常快,900多个渠道不到一分钟就能打完。
但是好景不长,在Android 7.0(Nougat)推出了新的应用签名方案APK Signature Scheme v2
后,之前快速生成渠道包的方式(美团Android自动化之旅—生成渠道包)已经行不通了(当然,我们可以暂时通过设置v2SigningEnabled false
来继续通过之前的方式打包,但最好还是应该接受新的改变),因为之前的签名方案并不会校验META-INF
目录,因而我们对该目录的修改并不需要重新签名。而新的方案下,我们对apk中包含的文件的任何修改,都会引起校验失败。这时美团推出了第二代多渠道打包方案Walle。
第二代多渠道打包方案Walle的思路其实就是从Zip文件本身入手,因为apk本质上还是一个Zip文件,美团通过在ZIP文件格式的 Central Directory
区块所在文件位置的前面添加一个APK Signing Block
区块,然后把渠道信息写到这个区块中,之后再读出这个信息,就完成了。当然,实际细节比较复杂。具体可以参考新一代开源Android渠道包生成工具Walle,据说这种打包方式速度非常快,对一个30M大小的APK包只需要100多毫秒(包含文件复制时间)就能生成一个渠道包,而在运行时获取渠道信息只需要大约几毫秒的时间。
在接入Walle之前,我们需要创建好签名文件,并且在项目的build.gralde中进行配置,类似这种:
signingConfigs {
myConfig {
storeFile file("../Walle.jks")
storePassword "abc12345"
keyAlias "Walle"
keyPassword "abc12345"
}
}
buildTypes {
debug {
signingConfig signingConfigs.myConfig
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
release {
signingConfig signingConfigs.myConfig
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
具体关于如何创建签名文件,可以参考:
Android Studio下应用签名的方法以及获取 MD5、SHA1(签名)、SHA256 值,关于keystone签名文件更详细的知识,可以参考:Android Keystore漫谈
美团Walle
具体接入方法可以参考:https://github.com/Meituan-Di...
这里其他我们都按照默认即可,只需要根据自己的需要来编写channel
文件即可,注意,这个文件不能有任何后缀。
集成Walle
后我们就可以通过
String channel = WalleChannelReader.getChannel(this.getApplicationContext());
来获取channel,然后把该channel传给友盟进行渠道的统计:
UMConfigure.init(Context context, String appkey, String channel, int deviceType, String pushSecret);
然后我们需要进行多渠道打包的时候,只需要执行./gradlew clean assembleReleaseChannels
即可来生成所有的渠道包
有时候执行该命令,我们可能会遇到R.java文件丢失的问题,但是通过AS的clean
又能重新生成,这时候我们可以把上述命令中的clean去掉,变为通过命令./gradlew assembleReleaseChannels
生成
所有渠道包。
这样,我们就完成了渠道包的生成,如果想验证是否能在代码中成功获取到渠道信息,我们可以在友盟的管理后台查看,也可以直接通过Log
在代码中输出到Logcat
中
三、进行360加固
相信任何在公司从事过App开发的,都知道应用在上线之前应该进行加固,但是我还是在应用市场上见过没加固的,直接使用jadx
反编译之后,每一行代码都能清清楚楚的看到,跟他们相关人员联系后,给我的答案是:“我们知道没有加固,这点我们很早就清楚。” “(⊙o⊙)…我.....”,然后还反问我一句:“你知道吗,你用加固的话,那些加固厂商可能会在你apk里加入些东西”...我都无fuck说了,那你还集成那么多的第三方服务干嘛,他们就不会添加?这就是裸奔的理由?好了,吐槽结束。我们在发布apk到应用市场的时候,一定要进行apk加固,如果实在是信不过加固厂商,自己又牛逼的很的话,就自己写吧。
这里用的比较多的就是360加固了,使用也很简单,就是讲自己打包好的apk上传上午,加固好之后再下载加固后的包即可。具体可以查看360加固官网
这看起来一切流程都已经完成了,我们就一个个把第二步中生成的那些渠道一个个上传到360进行加固,然后下载下来不就行了。首先,如果渠道太多的话,这个是要死人的。更要命的是,当你一个个加密之后,竟然发现这些都不能用,获取不到渠道信息的时候
其实,这里就涉及到一个问题,我们直接通过美团Walle多渠道方案打包生成的apk,在经过360加固之后,是会丢掉渠道信息的,那么如何解决呢,美团在GitHub上也提出了解决方案360加固失效?
作为懒人,繁琐的一步步自己去做是不可能,这辈子都可能的。这里我们就直接采用Jay-Goo
大佬提供的Python打包脚本ProtectedApkResignerForWalle,这也是美团官方推荐的方案。接下来我们就讲解如果使用该脚本
四、解决360加固丢失渠道信息的问题
这里我们使用ProtectedApkResignerForWalle解决360加固丢失渠道信息的问题,可以直接去ProtectedApkResignerForWalle仓库查看,很简单。这里我只是将其他一些需要注意的事情讲下。
- 生成一个发布版的包,可以通过执行
assembleRelease
这个task
或者通过工具栏上面的Build下面的Generated Signed Apk
- 将这个apk通过360网页版进行加固(通过其提供的桌面工具加固的话会自动使用V1方式签名),然后下载下来加固之后的apk,比如叫:
release.encrypted.apk
- 通过
git clone https://github.com/Jay-Goo/ProtectedApkResignerForWalle.git
命令来将仓库clone
下来,然后把步骤1中生成的release.encrypted.apk
放入该项目的根目录,并根据按照config.py文件中的注释改成自己项目配置 - 根据项目情况修改channel这个文件中,如果之前配置Walle的时候已经写了,直接复制过来就好,之前位置的channel文件就没用了,以后我们只需要维护这个channel文件即可
- 运行命令 python ApkResigner.py,即可自动生成所有渠道包。之后我们即可在该仓库的channels文件夹下看到生成的各种渠道包了
最后,我们需要通过jadx
反编译利器来随意查看某个apk是否加固成功,再安装试试,看是否能正常获取渠道信息。没问题的话,就开心的加班发布去吧。