本篇文章已授权微信公众号 guolin_blog (郭霖)独家发布
通过浏览这篇文章,我们可以学习以下内容:
生成签名文件,手动打包
首先生成签名文件,点击 Build -> Generate Signed APK
:
如果还没有签名文件,点击构造一个:
图中圈住的三个地方是重要信息,其余随意填。
生成以后,就可以用该签名文件继续签名打包:
填入刚才的信息,继续:
选好输出路径,选择打包类型,完成!
通过配置自动打包
如果你觉得上述打包步骤太麻烦,那么我们就开始在gradle里添加配置,自动打包。
快捷键 Ctrl+Alt+Shift+S
或者 File -> Project Structure
:
选择 application
,在 Signing
标签下添加签名配置,这里的 Store File
就是我们的签名文件。
我们还可以继续添加构建类型,选择 Build Types
标签,添加 release,选择刚才的签名配置:
这样我们就有了debug和生产类型的两种打包方式,以后就可以根据需要自动打包。选中工程,点击 Build -> Select Build Variant
,选择 release
:
然后点击 Build -> Build APK
,打包文件在..\app\build\outputs\apk
,如此便使用我们自己的签名文件,打好了一个生产包。同样也可以打出debug包,如果在Build Types
中我们没有设置Signing Config
,系统默认使用自带的debug签名文件打包。
隐藏签名文件敏感信息
我们设置过打包配置以后,Gradle 自动 Sync,会在application的 build.gradle
文件中生成下面代码:
signingConfigs {
config {
keyAlias 'gaok_release'
keyPassword '199110'
storeFile file('E:/GK/gaok.jks')
storePassword '199110'
}
}
这些都是签名文件的敏感信息,如果我们在协同开发的时候,最好把这些信息隐藏掉。
首先在工程根目录下新建一个 keystore.properties
文件:
storePassword=199110
keyPassword=199110
keyAlias=gaok_release
storeFile=E:/GK/gaok.jks
这里要注意:所有属性都没有单引号
然后再在 build.gradle
文件的如下位置添加:
apply plugin: 'com.android.application'
// Create a variable called keystorePropertiesFile, and initialize it to your
// keystore.properties file, in the rootProject folder.
def keystorePropertiesFile = rootProject.file("keystore.properties")
// Initialize a new Properties() object called keystoreProperties.
def keystoreProperties = new Properties()
// Load your keystore.properties file into the keystoreProperties object.
keystoreProperties.load(new FileInputStream(keystorePropertiesFile))
android {
……
}
读取到 keystore.properties
文件,然后更改配置:
android {
signingConfigs {
config {
keyAlias keystoreProperties['keyAlias']
keyPassword keystoreProperties['keyPassword']
storeFile file(keystoreProperties['storeFile'])
storePassword keystoreProperties['storePassword']
}
}
}
这样,所有的敏感信息都放在了文件里,只需要好好保存 keystore.properties
文件就行了,记得可别把文件也传到git里!
通过设置风味实现不同风味包的资源替换
什么是风味?看这个图:
我们在 Flavors
标签下可以添加多个“风味”,以满足个性化需要。
设置完风味以后,我们的 build.gradle
文件会生成如下:
productFlavors {
huawei {} // 华为商店
baidu {} // 百度手机助手
yinyongbao {} // 应用宝
}
比如这里我添加了多个应用市场的渠道,每个渠道可能要适配不同的SDK版本;
也可能我想要实现不同风味包(例如:生产和debug模式)的logo不同、某些代码不同,那我们就可以设置源集目录,专门收录不同不同配置下的代码和资源文件。
首先切换到Project视图,我们的工程默认是只有 main
源集,即 ../src/main
。
下面添加一个debug类型的源集:
这里的Target Source Set
会包含buildTypes
、productFlavors
和二者的组合变体。我这里设置了debug
和release
两种类型,huawei、yingyongbao、baidu
三种风味,所以会出现上图中这么多选项。我们选择debug,系统自动给我们的工程生成了对应目录。
同样的可以添加XML文件目录:
我这里添加了values
文件,同理可以添加colors、strings、styles
文件。
继续添加图片资源:
这里只是示例,我选择了一个不同的图标:
这里提示:图标名字重复,因为main源集里已经有ic_launcher
图标了,不过没关系,我们在下一步选择debug
源集:
最终目录如下:
现在我们有了debug源集,源集里有一个不同的app logo
,这意味着,如果我们现在打了debug包,它的图标将会是debug源集下的图标,如下图,左侧是debug
包,右侧是release
包。
至于我为什么可以同时装上debug包和release包,因为我添加了applicationIdSuffix
:
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
signingConfig signingConfigs.config
applicationIdSuffix ".release"
}
debug {
signingConfig signingConfigs.config
applicationIdSuffix ".debug"
}
}
applicationIdSuffix
字段表示:在不改变你默认的程序ID(包名)的情况下,为其添加后缀。比如你的包名是com.gk.app
,但你想区分测试包和正式包的情况,这个时候将applicationIdSuffix
设置为.debug
,那么你的应用程序对应的包名就变成了com.gk.app.debug
多渠道打包
工作中,软件包的发布工作一般是由运营小伙伴完成,包名格式一般会是:app + 版本号 + 渠道
,不同渠道可能要进行不同的配置,因此我们必须针对所有渠道添加对应的风味。
android{
productFlavors {
//三个渠道
huawei {} // 华为商店
baidu {} // 百度手机助手
yinyongbao {} // 应用宝
}
// 批量渠道包值替换(有些第三方库中需要用到渠道名)
productFlavors.all { flavor ->
// 友盟、极光推送渠道包, UMENG_CHANNEL 是根据你AndroidManifest.xml来配置的,请看下面。
flavor.manifestPlaceholders = [UMENG_CHANNEL: name, JPUSH_CHANNEL: name]
}
}
这里的UMENG_CHANNEL
是在AndroidManifest.xml
文件中配置的:
<!--变量采用${变量名}这样来替换,不局限于<meta-data/> 标签,任何你想替换的都行-->
<meta-data
android:name="UMENG_APPKEY"
android:value="${UMENG_APPKEY}"/>
然后批量重命名:
android{
……
// 输出文件配置,格式如下:app-{版本号}-{渠道名称}.apk
applicationVariants.all { variant ->
variant.outputs.each { output ->
def outputFile = output.outputFile
if (outputFile != null && outputFile.name.endsWith('.apk')) {
def dirName = outputFile.parent // 输出文件夹所在的位置
// 文件名修改
def fileName = "app-${defaultConfig.versionName}-${variant.flavorName}.apk"
output.outputFile = new File(dirName, fileName)
}
}
}
……
}
如此再看Select Build Variant
:
我们打一个baidu release
包:
同理,多渠道打包完成。