概述
- 打包:根据签名和其他标识生成安装包。
- 签名:在APK中保存唯一标识符,版权标识,也避免包名相同导致应用的覆盖。
- 多渠道打包:在APK中添加渠道唯一标识符,便于做数据统计。
- 生成签名文件及友盟多渠道打包步骤。
生成签名文件
1. Build --- Generate Signed APK --- Create new
2. 填写保存路径、密码及App相关信息 --- OK
友盟多渠道打包
1. 注册登录友盟 --- 创建新应用 --- 生成Appkey
2. 在AndroidManifest.xml中配置友盟Appkey和渠道名占位符
<!-- 友盟Appkey -->
<meta-data
android:name="UMENG_APPKEY"
android:value="刚生成Appkey" />
<!-- 渠道名占位符 -->
<meta-data
android:name="UMENG_CHANNEL"
android:value="${UMENG_CHANNEL_VALUE}" />
3. 在应用app的build.gradle中注入友盟库依赖
dependencies {
compile 'com.umeng.analytics:analytics:latest.integration'
}
不用友盟以上步骤只留 ‘ 占位符 ’ 即可。
4. 签名
// 1. 配置签名
signingConfigs {
debug {}
// 给发布版配置
release {
storeFile file("ApkPack.jks")
storePassword "111111"
keyAlias "ApkPack"
keyPassword "222222"
}
}
// 2. 添加签名
signingConfig signingConfigs.release
5. 在应用app的build.gradle中编写脚本,动态替换渠道占位符。
// 渠道名
productFlavors{
Aa{}
Bb{}
Cc{}
}
productFlavors.all { flavor ->
flavor.manifestPlaceholders = [UMENG_CHANNEL_VALUE: name]
}
6. 指定APK文件名规则 --- 渠道名_版本号.apk
applicationVariants.all { variant ->
variant.outputs.each { output ->
def outputFile = output.outputFile
if (outputFile != null && outputFile.name.endsWith('.apk')) {
def fileName = "${variant.productFlavors[0].name}" + "_${defaultConfig.versionName}.apk"
output.outputFile = new File(outputFile.parent, fileName)
}
}
}
7. Terminal控制台 --- gradlew assembleRelease --- 完成所有版本的打包
- 只打包Aa的release --- gradlew assembleAaRelease
- 只打包Aa的debug --- gradlew assembleAaRelea
- 打包Aa的2个版本 --- gradlew assembleAa
1. 如果没有gradle,Android Studio会自行下载
2. 由于下载太慢,也不显示进度,可手动下载https://downloads.gradle.org/distributions/gradle-2.14.1-all.zip
3. 解压后放到C:\Users\Administrator\.gradle\wrapper\dists即可
4. 文件夹名一定要是gradle-2.14.1-all,与下载包文件名一致
完整代码
1. AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.eczom.apkpack">
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<!-- 友盟Appkey -->
<meta-data
android:name="UMENG_APPKEY"
android:value="58c583bec72dca7a5800078b" />
<!-- 渠道名占位符 -->
<meta-data
android:name="UMENG_CHANNEL"
android:value="${UMENG_CHANNEL_VALUE}" />
</application>
</manifest>
2. build.gradle
apply plugin: 'com.android.application'
android {
compileSdkVersion 25
buildToolsVersion "25.0.2"
defaultConfig {
applicationId "com.eczom.apkpack"
minSdkVersion 15
targetSdkVersion 25
versionCode 1
versionName "1.0"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
}
// 配置签名
signingConfigs {
debug {}
// 给发布版配置
release {
storeFile file("ApkPack.jks")
storePassword "111111"
keyAlias "ApkPack"
keyPassword "222222"
}
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
// 添加签名
signingConfig signingConfigs.release
// 渠道名
productFlavors {
Aa {}
Bb {}
Cc {}
}
productFlavors.all { flavor ->
flavor.manifestPlaceholders = [UMENG_CHANNEL_VALUE: name]
}
// 指定APK文件名规则 --- 渠道名_版本号.apk
applicationVariants.all { variant ->
variant.outputs.each { output ->
def outputFile = output.outputFile
if (outputFile != null && outputFile.name.endsWith('.apk')) {
def fileName = "${variant.productFlavors[0].name}" + "_${defaultConfig.versionName}.apk"
output.outputFile = new File(outputFile.parent, fileName)
}
}
}
}
}
}
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
exclude group: 'com.android.support', module: 'support-annotations'
})
compile 'com.android.support:appcompat-v7:25.2.0'
testCompile 'junit:junit:4.12'
//友盟库依赖
compile 'com.umeng.analytics:analytics:latest.integration'
}