apk打包相关简单总结

本文主要总结一些打包相关的简单技巧


以下为build.gradle文件简单操作总结

配置签名信息

1
2
3
4
5
6
7
8
9
signingConfigs {//签名配置
Config {//配置名
storeFile file(propertyStoreFileStr)//签名文件
storePassword propertyStorePwdStr//密码
keyAlias propertyKeyAliasStr//别名账号
keyPassword propertyKeyPwdStr//别名账号密码
v2SigningEnabled false//是否使用v2 签名 (注意:v2签名安全性高,但使用美团修改文件名区分渠道后,由于无法将修改文件签名,就会导致在android7.0及以上就无法安装。 如果不做apk文件的修改则不会存在这样的问题,可以开启。)
}
}

buildTypes 构建不同的环境渠道

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
buildTypes {
if (propertyHaveSigningConfigs)
debug {
minifyEnabled false//是否进行混淆
shrinkResources false //是否清理无用资源
zipAlignEnabled false//是否启用zipAlign压缩
}
release {
applicationIdSuffix ".release"//包名添加一级 top.goluck.release_2017_6_30.meizu.release
minifyEnabled true//是否进行混淆
shrinkResources true //是否清理无用资源
zipAlignEnabled true//是否启用zipAlign压缩
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'//使用混淆文件
signingConfig signingConfigs.Config//引用指定配置
}
}

applicationVariants 示例重命名APK

1
2
3
4
5
6
android.applicationVariants.all { variant ->
variant.outputs.all {
outputFileName = "Release_2017_6_30-${variant.versionName}-${variant.buildType.name}.apk".toLowerCase()
}
}
~

lintOptions 忽略错误

1
2
3
lintOptions {
abortOnError false
}

多渠道处理修改aar输出目录和名称

1
2
3
4
5
6
7
8
9
10
11
12
13
libraryVariants.all { variant -> 
if (variant.buildType.name == "debug") {
variant.getPackageLibrary().destinationDir = new File(project.rootDir.absolutePath + "/xxx")
}
if (variant.buildType.name == 'debug') {
variant.outputs.all {
output -> def outputFile = output.outputFile
if (outputFile != null && outputFile.name.endsWith('debug.aar')) {
outputFileName = "${project.name}-${variant.flavorName}-${variant.buildType.name}.aar"
}
}
}
}

引入本地脚本 使用参考定义变量及使用

  • 可在当前gradle中使用引入的gradle参数方法等
    1
    apply from: '../config/properties-util.gradle'//引用本地gradle文件

取消指定task任务 比如不执行AndroidTest

1
2
3
4
5
6
tasks.whenTaskAdded { task ->
if (task.name.contains('AndroidTest')) {
task.enabled = false
}
}
~

定义变量及使用

1
2
3
4
5
6
7
8
9
10
//定义变量
ext{
compileSdk = 26
buildTools = "26.0.0"
}
//使用
android {
compileSdkVersion compileSdk //编译使用的版本号
buildToolsVersion buildTools//buildTools版本号
}

productFlavors 构建不同的渠道

  • buildConfigField 配置的数据会在BuildConfig中生成。可以在程序中使用它
  • manifestPlaceholders 可以用于替换AndroidManifest.xml中的占位符 可以在程序中获取该值
    • 例如 以下是获取更换了UMENG_CHANNEL值的kotlin代码
      1
      2
      3
      4
      5
      6
      7
      8
      9
      fun getUMENG_CHANNEL(): String? {
      var appInfo: ApplicationInfo? = null
      try {
      appInfo = packageManager.getApplicationInfo(packageName, PackageManager.GET_META_DATA)
      } catch (e: PackageManager.NameNotFoundException) {
      e.printStackTrace()
      }
      return appInfo!!.metaData.getString("UMENG_CHANNEL")
      }
  • 可在此操作
    • 配置不同渠道
    • 配置不同包名
    • 配置不同版本号
    • 提供不同的依赖
    • 提供不同的源码及资源
      • 比如需要huawei渠道使用huawei渠道的logo
      • 即在main同级目录创建huawei目录
      • 同main目录一样在同样目录下放同名资源即可覆盖
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
flavorDimensions "default"
//设置多渠道
productFlavors {
// 把指定渠道的apk中的AndroidManifest中的channel替换指定渠道名
meizu {
buildConfigField("String", "channel", "\"meizu\"")//给配置添加一个String的类型记录渠道名
// manifestPlaceholders = [UMENG_CHANNEL_VALUE:"meizu"]
applicationIdSuffix ".meizu"//包名添加一级 top.goluck.release_2017_6_30.meizu
versionName "2.0" //更改版本号
}
huawei {
buildConfigField("String", "channel", "\"huawei\"")//给配置添加一个String的类型记录渠道名
// manifestPlaceholders = [UMENG_CHANNEL_VALUE:"huawei"]
}
baidu {
buildConfigField("String", "channel", "\"baidu\"")//给配置添加一个String的类型记录渠道名
// manifestPlaceholders = [UMENG_CHANNEL_VALUE:"baidu"]
}
}
// 批量配置渠道
productFlavors.all {
flavor -> flavor.manifestPlaceholders = [UMENG_CHANNEL_VALUE: name]
}

//指定渠道导入指定第三方库
dependencies {
meizuImplementation "com.android.support:appcompat-$appcompat" //(meizu渠道所有包)引入v7向下兼容包
debugImplementation "com.android.support:appcompat-$appcompat" //(所有渠道debug包)引入v7向下兼容包
}

gradle文件中读取properties 文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
Properties gradleProperties = new Properties()//new 一个Properties对象
gradleProperties.load(project.rootProject.file('config/gradle.properties').newDataInputStream())//初始相对路径的config/gradle.properties下的该Properties对象
def storeFileStr = gradleProperties.getProperty('RELEASE_STORE_FILE',null)//读取签名文件地址
def storePwdStr = gradleProperties.getProperty('RELEASE_STORE_PASSWORD', null)//读取密码 默认读取不到为null
def keyAliasStr = gradleProperties.getProperty('RELEASE_KEY_ALIAS', null)//别名账号 默认读取不到为null
def keyPwdStr = gradleProperties.getProperty('RELEASE_KEY_PASSWORD', null)//别名账号密码 默认读取不到为null
//赋值到变量用于配置签名
ext {
propertyHaveSigningConfigs = (storeFileStr != null && storePwdStr != null && keyAliasStr != null && keyPwdStr != null)
propertyStoreFileStr = storeFileStr
propertyStorePwdStr = storePwdStr
propertyKeyAliasStr = keyAliasStr
propertyKeyPwdStr = keyPwdStr
}

动态生成string字符串

1
2
3
4
5
6
7
8
//生成build_time字符
android {
defaultConfig {
resValue "string", "build_time", new Date().format("yyyy-MM-dd HH:mm:ss")
}
}
// 在Activity里使用build_time字符
getString(R.string.build_time) // 输出2017-06-30 18:30

debug、release 默认配置

Property name Default values for debug Default values for release / other
debuggable true false
jniDebugBuild false false
renderscriptDebugBuild false false
renderscriptOptimLevel 3 3
packageNameSuffix null null
versionNameSuffix null null
signingConfig android.signingConfigs.debug null
zipAlign false true

defaultConfig {} 配置参数列表

Property Name Default value in DSL object Default value
versionCode -1 value from manifest if present
versionName null value from manifest if present
minSdkVersion -1 value from manifest if present
targetSdkVersion -1 value from manifest if present
packageName null value from manifest if present
testPackageName null app package name + “.test”
testInstrumentationRunner null android.test.InstrumentationTestRunner
signingConfig null null
runProguard false false
proguardFile ‘proguard-android.txt’ or ‘proguard-android-optimize.txt’ ‘proguard-android.txt’ or ‘proguard-android-optimize.txt’

打包等各种操作

  • 打包等操作

    • 打开 View -> Tool Windows -> Gradle 即可看到所有可以的操作。比如:
      • build 下,可以直接双击assembleRelease生成所有release包 (生成apk地址:app->build->ouputs->apk)
    • 或打开 View -> Tool Windows -> Terminal 控制台,直接输入命令gradle assembleRelease生成所有release包,生成目录同上
  • 打开View -> Tool Buttons 选择 Build Variants 可切换直接运行生成的apk的build variant类型

统一修改依赖库版本号

  • 例如以下修改 com.android.support 组下,排除multidex的所以库,统一版本号为25.3.1
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    configurations.all {
    resolutionStrategy.eachDependency { DependencyResolveDetails details ->
    def requested = details.requested
    if (requested.group == 'com.android.support') {
    if (!requested.name.startsWith("multidex")) {
    details.useVersion '25.3.1'
    }
    }
    }
    }

相关参考