美文网首页
Android从多渠道打包到Gradle批量拷贝文件

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

作者: Dapengyou | 来源:发表于2018-08-21 15:22 被阅读92次

    前言

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

    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批量拷贝文件

          本文链接:https://www.haomeiwen.com/subject/rjbxbftx.html