本文没有说起到啥新技术,相反的,都是看几年前的技术,所以,本文不适合安卓开发同窗,对不了解的同窗会有必定的帮助;android
所以,请各位大牛勿喷,谢谢~ git
(一脸幽怨)这个事,终究仍是落在jb身上了,事情通过是这样的:github
每次发版本,安卓都须要上传N个商店,而不一样的渠道须要打不一样的渠道标识,
当APP和后台交互或者数据上报时,会带上各自的渠道信息。这样就能统计
到每一个分发市场的下载数、用户数等关键数据;
复制代码
这块呢,原本是让产品实习生负责,结果呢,过完年后,实习生要回校了,产品老大不肯意作这事,测试只剩下一我的了,顺其而然的,这事就落在jb身上; 安全
不幸中的万幸,以前这块是一测试妹子负责,当时让其写了个文档,总算有迹可循,一块儿看看目前我司是如何打渠道包的吧;bash
官网包闭包
先须要一个官网包,能够理解base包,适用于官网下载或者APP内手动、自动更新这些场景;app
360加固工具
有了官网包,而后就须要打渠道包的工具,我司用的是360加固工具;测试
连接:https://pan.baidu.com/s/1sPRt2vxdXegSBV_wEYH66A
提取码:nu47
复制代码
下载解压,稍后下,还须要两个文件,签名文件keystore及密码、渠道文件;gradle
两个文件准备好,打开exe、注册、登陆、添加信息(乱写便可),就会看到这货的界面;
点击应用加固-签名设置、多渠道设置,分别上传对应的keystore文件跟渠道文件;
而后点击添加应用,选择应用,而后就等着渠道包出来吧;
而后再手动去对应的渠道平台官网上传提交审核就能够了;
这个流程完,看着也很简单,没啥特别的,可是为啥要说这个事?
由于keystore不能随便给的啊!!!
既然如此,这种方式存在安全性问题,所以不建议使用,那怎么办?
在没有源码的事情下,想到的就是反编译
,而平常用的最多的就是apktool
工具;
流程是这样的:
这里说明几个点:
从新打包apk
apkapktool b newApkDir
复制代码
从新打包的apk会在newApkDir\dist
下;
签名
这里有两种状况,没有签名跟有签名,当没有签名时,须要先生成keystore
文件;
keytool -genkey -alias jb.keystore -keyalg RSA -validity 20000 -keystore jb.keystore
复制代码
输入后须要输入点内容:
jb.keystore
文件;
有前面文件后,接下来就是签名了;
jarsigner -verbose -keystore jb.keystore -signedjar jb_signed.apk jb.apk jb.keystore
复制代码
这里说明下,jb.apk
就是从新打包后的apk,jb_signed.apk
就是要生成的apk;
keystore
文件,若是别人的APP使用本身的
keystore
,普通功能是没问题的,可是一旦须要登陆功能,就会报错,提示签名跟XX平台的签名不一致;
怎么解决这问题?直接xp,这里就不展开了;
本身搞的前提是得有源码,若是连代码权限都没有,那就放弃吧;
而下面的例子只会使用demo来简单演示;
只有一个渠道标识
在AndroidManifest.xml
hardcode对应的曲奥标识;
<meta-data android:value="jbtest" android:name="CHANNEL"/>
复制代码
多个渠道标识
AndroidManifest.xml
添加渠道信息占位符;
<meta-data android:name="CHANNEL" android:value="${CHANNEL}" />
复制代码
在build.grade
设置productFlavors
标签添加渠道信息:
android{
productFlavors{
"jb"{
manifestPlaceholders = [CHANNEL : "jb"]
}
"jb2"{
manifestPlaceholders = [CHANNEL : "jb2"]
}
}
}
复制代码
这样,Gradle
编译生成多渠道包时,会用不一样的渠道信息替换AndroidManifest.xml
中的占位符;
缺点很明显,每生成一个渠道包,都要从新执行构建流程,国内渠道如此丰富,效率过低了;
这是落魄安卓同窗提供的,github地址点这里;
虽然github里面把每一步都讲的很清楚,可是由于懒,因此仍是想这里贴一下gradle
接入的步骤:
1.修改项目根目录下build.gradle文件,在buildscript下的dependencies中增长:
classpath 'com.meituan.android.walle:plugin:1.1.6'
复制代码
完整以下:
buildscript {
repositories {
google()
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:3.1.4'
classpath 'com.meituan.android.walle:plugin:1.1.6'
}
}
复制代码
2.修改app工程的build.gradle文件,增长以下信息:
1)头部增长:
apply plugin: 'walle'
复制代码
2)须要在buildTypes
中加signingConfig
,不然报这个错: Error:Plugin requires 'APK Signature Scheme v2 Enabled' for release.
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
signingConfig signingConfigs.release
}
debug {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
signingConfig signingConfigs.debug
}
}
复制代码
这里说明下signingConfig
,是须要一个keystore
,对这块有疑问的同窗,请点击这里查看;
3)配置wallet信息
walle {
// 指定渠道包的输出路径
apkOutputFolder = new File("${project.buildDir}/outputs/channels");
// 定制渠道包的APK的文件名称
apkFileNameFormat = '${appName}-${packageName}-${channel}-${buildType}-v${versionName}-${versionCode}-${buildTime}.apk';
// 渠道配置文件
channelFile = new File("${project.getProjectDir()}/channel")
}
复制代码
4)dependencies
新增 compile
:
dependencies {
implementation 'com.meituan.android.walle:library:1.1.6'
}
复制代码
完整的APP
下的build.grade
内容以下:
apply plugin: 'com.android.application'
apply plugin: 'walle'
android {
compileSdkVersion 28
defaultConfig {
applicationId "com.example.jb.myapplication"
minSdkVersion 15
targetSdkVersion 28
versionCode 1
versionName "1.0"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
signingConfig signingConfigs.release
}
debug {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
signingConfig signingConfigs.debug
}
}
}
walle {
// 指定渠道包的输出路径
apkOutputFolder = new File("${project.buildDir}/outputs/channels");
// 定制渠道包的APK的文件名称
apkFileNameFormat = '${appName}-${packageName}-${channel}-${buildType}-v${versionName}-${versionCode}-${buildTime}.apk';
// 渠道配置文件
channelFile = new File("${project.getProjectDir()}/channel")
}
dependencies {
implementation fileTree(include: ['*.jar'], dir: 'libs')
implementation 'com.android.support:appcompat-v7:28.0.0'
implementation 'com.android.support.constraint:constraint-layout:1.1.3'
testImplementation 'junit:junit:4.12'
androidTestImplementation 'com.android.support.test:runner:1.0.2'
androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
implementation 'com.meituan.android.walle:library:1.1.6'
}
复制代码
3.添加 channel 渠道文件
直接在APP目录下添加名为channel
的文件,内容是须要的渠道信息;
anzhuo
anfen
anbei
PC6
360
yingyongbao
baidu
wandoujia
pp
xiaomi
oppo
lenovo
huawei
复制代码
4.获取渠道
在须要获取渠道信息的地方使用以下代码获取渠道信息:
String channel = WalleChannelReader.getChannel(this.getApplicationContext());
复制代码
4.获取渠道
生成渠道包的方式是和assemble${variantName}Channels
指令结合, 渠道包的生成目录默认存放在 build/outputs/apk/
,也能够经过walle闭包中的apkOutputFolder
参数来指定输出目录;
生成渠道包
gradlew clean assembleReleaseChannels
支持 productFlavors
gradlew clean assembleMeituanReleaseChannels
生成单个渠道包
gradlew clean assembleReleaseChannels -PchannelList=anzhuo
生成多个渠道包
gradlew clean assembleReleaseChannels -PchannelList=wandoujia,baidu
Mac的话,就是./gradlew;
复制代码
原理
原理的话,就是在META-INF
目录内添加空文件
,能够不用从新签名应用,经过为不一样渠道的应用添加不一样的空文件,能够惟一标识一个渠道;
每打一个渠道包只需复制一个apk,在META-INF中添加一个使用渠道号命名的空文件便可;
这块的话,网上有大神把脚本开源了,网站自个儿找下吧;
须要的一些环境跟工具,请本身网上了解配置吧;
使用的是jarsigner命令;
jarsigner -certs -verbose -verify xxx.apk
复制代码
使用aapt命令;
aapt dump badging xxx.apk
复制代码
反编译apk,jb用的是apktool
工具,2.4.1
版本;
连接:https://pan.baidu.com/s/1MPWTfXIGzeOUpGZplEkveA
提取码:6h08
复制代码
apktool d XX.apk
复制代码
而后会生成一个目录,直接找到AndroidManifest.xml
文件,通常经常使用的是友盟,所以直接搜索UMENG_CHANNEL
,若是用的是别的,请自行搜索;
凡事都须要落地,那如何落地?
上面的方案,毫无疑问是选择第三种,实践也很简单,直接在jenkins新增打渠道包的选项便可
本文主要是经过3种方式来说述安卓多渠道包的方式,旧内容,对没了解过的同窗有必定的帮助,就这样吧~