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地址

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 160,108评论 4 364
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,699评论 1 296
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 109,812评论 0 244
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,236评论 0 213
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,583评论 3 288
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,739评论 1 222
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,957评论 2 315
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,704评论 0 204
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,447评论 1 246
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,643评论 2 249
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,133评论 1 261
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,486评论 3 256
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,151评论 3 238
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,108评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,889评论 0 197
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,782评论 2 277
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,681评论 2 272

推荐阅读更多精彩内容

  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 170,577评论 25 707
  • 目录一、Python打包及优化(美团多渠道打包)二、Gradle打包三、其他打包方案:修改Zip文件的commen...
    守望君阅读 5,625评论 4 17
  • 这一章主要针对项目中可以用到的一些实用功能来介绍Android Gradle,比如如何隐藏我们的证书文件,降低风险...
    acc8226阅读 7,482评论 3 25
  • 好对不起自己!从没让那些不看好自己的人后悔?
    常小识阅读 588评论 0 0
  • 南宁美女,QQ75140683 北京姑娘:华贵 美丽评价:中上 天津姑娘:清丽 美丽评价:中上 河北姑娘:文静 美...
    杰西软件站客服阅读 872评论 0 0