Android从多渠道打包到Gradle批量拷贝文件

前言

这篇文章主要描述四个部分:

  1. 如何生成一个证书
  2. gradle如何配置
  3. 批量打包
  4. 批量拷贝文件

如何生成一个证书

生成一个证书还是很简单了,需要完成下面的三步走:

第一步,点击build->选择Generate Signed APK,如下图:


Generate Signed APK

第二步,选择Generate Signed APK之后点击下一步,进入下图页面,并点击create new key store(图中圈出部分)

第三步,在 Android Studio 中创建新的密钥库:

密钥库

  • Key store path:选择创建密钥库的位置。
  • Password:为您的密钥库创建并确认一个安全的密码。

密钥

  • Alias:为您的密钥输入一个标识名。
  • Password:为您的密钥创建并确认一个安全的密码。此密码应当与您为密钥库选择的密码不同
  • Validity (years):以年为单位设置密钥的有效时长。密钥的有效期应至少为 25 年,以便您可以在应用的整个生命期内使用相同的密钥签署应用更新。
  • Certificate:为证书输入一些关于您自己的信息。此信息不会显示在应用中,但会作为 APK 的一部分包含在您的证书中。

表单如下图,填写完成后点击 OK

这种生成证书的方式不仅是这一种,但是这种事我认为的最简单最傻瓜式的,其他的生成证书方式如命令行的形式以及其他形式,有兴趣的可以参考下列文档

参考文档

gradle配置

如果使用上述方式,每次打包的时候都要点好几次,但是项目一旦运行在没有配置证书的电脑上,还要复制已经生成好的证书,重新输入密码进行配置,感觉有点小繁琐,那么现在只要在gradle进行一番配置就可以免除这些烦恼。看下面是如何配置的。

下文出现的aidl.jks文件是我用第一种方法生成好的证书,放在App文件下,文后提供了源码可供参考

android {
    compileSdkVersion 27
    defaultConfig {
        //唯一标识一个app,修改这个可以在多渠道打包时,让同个app的不同构建包同时安装在一台设备上
        applicationId "com.test.aidl"
        //指定运行需要的最小API版本
        minSdkVersion 19
        //指定用来测试的API版本
        targetSdkVersion 27
        //app版本号
        versionCode 1
        //app版本名
        versionName "1.0"
        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
    }

    //签名
    signingConfigs {
        release {
            storeFile file("aidl.jks")
            storePassword "123456"
            keyAlias "key"
            keyPassword "123456"
        }
        debug {
            storeFile file("aidl.jks")
            storePassword "123456"
            keyAlias "key"
            keyPassword "123456"
        }
    }
    buildTypes {
        release {
            minifyEnabled false         //不启用Proguard
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
            signingConfig signingConfigs.release
        }
        debug {
            minifyEnabled false        //不启用Proguard
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
            signingConfig signingConfigs.debug
        }
    }

}

如此gradle就配置好了

批量打包

如果公司有需求要统计各大平台的App下载量,那么就会牵扯到将包名更改成指定的内容,如果只是改一两个那么我们手动改一下也无所谓,可是要是有10个20 个呢,那。。。手动更改包名就要累死宝宝们了,所以gradle 又帮我们一个大忙,可以编写代码进行批量打包,代码如下:

这里呢为了避免app包下的build.gradle文件过于冗长,我将批量打包的代码提出来了,放在cpoyApk.gradle文件中,cpoyApk.gradle文件存在的位置如下图

build.gradle文件中头部添加下面这句话,将文件引入

apply from: this.file('copyApk.gradle')

cpoyApk.gradle文件中代码:

this.android.flavorDimensions 'type'

this.android.productFlavors {
    //定义各大平台的名字
    googlepay {
        dimension 'type'
        manifestPlaceholders = [MTA_CHANNEL_VALUE: "googlepay"]
    }
    baidu {
        dimension 'type'
        manifestPlaceholders = [MTA_CHANNEL_VALUE: "baidu"]
    }
    qihoo360 {
        dimension 'type'
        manifestPlaceholders = [MTA_CHANNEL_VALUE: "qihoo360"]
    }
    xiaomi {
        dimension 'type'
        manifestPlaceholders = [MTA_CHANNEL_VALUE: "xiaomi"]
    }
    tencent {
        dimension 'type'
        manifestPlaceholders = [MTA_CHANNEL_VALUE: "tencent"]
    }
    anzhi {
        dimension 'type'
        manifestPlaceholders = [MTA_CHANNEL_VALUE: "anzhi"]
    }
}

// 指定apk名字输出格式
this.android.applicationVariants.all { variant ->
    variant.outputs.all {
        outputFileName = "aidl_${this.android.defaultConfig.versionName}_" +
                "${this.android.defaultConfig.versionCode}_" +
                "${variant.productFlavors[0].name}.apk"
    }
}

打包之后,所生成的apk的包名如下

我们可以看一下运行完上面的gradle代码,项目中的task有没有什么变化

mac系统可以使用终端找到当前项目,输入./gradlew task命令

Windows系统也可以在终端找到当前项目,输入gradlew task命令

会出现下面的task目录,这里只是截取了一部分,每个task后面都有对应的解释(黄色的就是解释)

如果不想输入命令行查看呢,也可在Android Studio最右边点击Gradle->app->Tasks->build 查看,如下图所示,同样可以查看task

那我为什么要介绍怎么查看task呢,那是因为。。。如果你只想生成360平台的apk,那么你找到assembleQihoo360 双击,就可以生成调试的apk以及正式的Apk,是不是很简单,或者是使用命令行./gradlew assembleQihoo360(mac系统下,Windows系统下将./去掉即可)

我们可以看下运行效果:

运行效果

批量拷贝文件

批量打包文件已经完成了,那我们总不能一个一个的把文件拷出来放在指定的目录下吧,于是乎,我又想到了用gradle实现批量拷贝文件到指定目录下,还是在cpoyApk.gradle文件中,代码如下:

//自定义copyApk task
task copyTask {
    doLast {
        def apkNameList = [
                "anzhi",
                "baidu",
                "googlepay",
                "qihoo360",
                "tencent",
                "xiaomi"
        ]
        //遍历
        apkNameList.each { def content ->

            def fileName = "aidl_${this.android.defaultConfig.versionName}_" +
                    "${this.android.defaultConfig.versionCode}_" +
                    "${content}.apk"

//        拷贝文件的始发地
            def sourceFile = "./build/outputs/apk/${content}/debug/" + fileName

//        指定文件拷贝的目的地
            def destationFile = new File(project.getProjectDir().path + "apk/")
            try {
//            判断文件夹是否存在
                if (!destationFile.exists()) {
                    destationFile.mkdir()
                }
                //拷贝
                copy {
                    from sourceFile
                    into destationFile

                    rename {
                        fileName
                    }
                }

            } catch (Exception e) {
                e.printStackTrace()
            }
        }
    }
}

这代码里是自定义了一个task,执行./gradlew copyTask,可以看到根目录下出现appapk文件夹,并且里面包含各大平台正式的apk,效果如下:

运行效果

但是光自定义task是不行的,还需要将自定义的task挂接到构建过程中,代码如下:

//挂接自定义task到构建过程中
this.project.afterEvaluate { project ->
//    获得build task
    def buildTask = project.tasks.getByName('build')
    if (buildTask == null) {
        throw GradleException('the build task is not found')
    }
    buildTask.doLast {
        copyTask.execute()
    }
}

最后我们来看下执行效果:

运行效果

github地址

你可能感兴趣的:(Android从多渠道打包到Gradle批量拷贝文件)