Android 多渠道多环境打包Apk

往往有时候会有打包多套App的需求,而这多个App的logo,启动页,引导页,applicationId,第三方分享key都不一样。放在以往我们的的做法往往使用多套代码进行修改之后再打包,费时费力,后来通过gradle可以轻松完成这个过程,打包也变得很简单。

gradle是一个基于Apache Ant和Apache Maven概念的项目自动化建构工具。他可以帮助我们轻松实现多渠道打包的功能,在这里我用多环境打包演示一下,因为多环境其实和多渠道一样的道理。
项目目录如下:

58BA6F93-08A8-4AF9-B1CA-7A0DA9723964.png

项目的gradle文件如下:

// Top-level build file where you can add configuration options common to all sub-projects/modules.

buildscript {
    repositories {
        jcenter()
    }
    dependencies {
        classpath 'com.android.tools.build:gradle:2.2.0'

        // NOTE: Do not place your application dependencies here; they belong
        // in the individual module build.gradle files
    }
}

allprojects {
    repositories {
        jcenter()
    }
}

task clean(type: Delete) {
    delete rootProject.buildDir
}

ext {
    // Sdk and tools
    minSdkVersion = 15
    targetSdkVersion = 24
    compileSdkVersion = 24
    buildToolsVersion = '24.0.1'
    versionCode=350
    versionName='3.5.0'

    //package
    applicationId='com.test'

    // App dependencies

}

App下的gradle文件

apply plugin: 'com.android.application'

//获取打包时间
def releaseTime() {
    return new Date().format("yyyyMMdd", TimeZone.getTimeZone("UTC"))
}
//获取local.properties的内容
Properties properties = new Properties()
properties.load(project.rootProject.file('local.properties').newDataInputStream())

android {
    compileSdkVersion rootProject.ext.compileSdkVersion
    buildToolsVersion rootProject.ext.buildToolsVersion

    defaultConfig {
        multiDexEnabled true
        applicationId rootProject.ext.applicationId
        minSdkVersion rootProject.ext.minSdkVersion
        targetSdkVersion rootProject.ext.targetSdkVersion
        versionCode rootProject.ext.versionCode
        versionName rootProject.ext.versionName
    }

    //添加签名文件
    signingConfigs{
        debug{}
        release{
            //为了保护签名文件,把它放在local.properties中并在版本库中排除
            //不把这些信息写入到版本库中(注意,此种方式签名文件中不能有中文)
            storeFile file(properties.getProperty("keystroe_storeFile"))
            storePassword properties.getProperty("keystroe_storePassword")
            keyAlias properties.getProperty("keystroe_keyAlias")
            keyPassword properties.getProperty("keystroe_keyPassword")
           注:这种方案并不是唯一方案,也可以采用直接在这里写死  但推荐以上方式。
        }
    }

    buildTypes {
        release {
            //允许混淆代码
            minifyEnabled true
            //打包过滤掉未引用资源文件
            shrinkResources true
            //引用混淆文件
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
            //设置打包签名
            signingConfig signingConfigs.release
           //批量修改打包之后的命名规则
            applicationVariants.all{  variants ->
                variants.outputs.each{ output ->
                    def outFile=output.outputFile
                    if (outFile!=null && outFile.name.endsWith(".apk"))
                    {
                        def fileName="diankeyuan_"+"${variants.productFlavors[0].name}"+"_V"+"${defaultConfig.versionName}"+"_${releaseTime()}"+".apk"
                        output.outputFile=new File(outFile.parent,fileName);
                    }
                }
            }
        }
    }


    sourceSets {
        main {
            aidl.srcDirs = ['src/main/java']
            jniLibs.srcDirs = ['libs']
            java.srcDirs = ['src/main/java']
            res.srcDirs = ['src/main/res']
            assets.srcDirs = ['assets']
            manifest.srcFile 'src/main/AndroidManifest.xml'
        }
    }
    allprojects {
        repositories {
            mavenCentral()
        }
    }
   //测试环境  预生产环境  生产环境
    productFlavors{
         mtesting{
             manifestPlaceholders = [app_name: "@string/app_name"]
         }
         preing{
             manifestPlaceholders = [app_name: "@string/app_name"]
         }
        normal{
            manifestPlaceholders = [app_name: "@string/app_name"]
        }
    }
  //在项目src目录下,建了mtesting,preing,normal目录,注意都在java目录下并且包名要一样,在项目代码
  //里   可以如下引用:
   **
     * 参数拼接,没有.do
     *
     * @param action
     * @return
     */
     // private String getUrlString(String action) {
     //   if (!action.equals("")) {
     //     return Api.baseurl + action;
     //   }
     //   return Api.baseurl + "/";
     //  }

}

dependencies {
    compile fileTree(include: ['*.jar'], dir: 'libs')
}

local.properties文件

## This file is automatically generated by Android Studio.
# Do not modify this file -- YOUR CHANGES WILL BE ERASED!
#
# This file must *NOT* be checked into Version Control Systems,
# as it contains information specific to your local configuration.
#
# Location of the SDK. This is only used by Gradle.
# For customization when using a Version Control System, please read the
# header note.
#Mon Oct 17 09:15:05 CST 2016
sdk.dir=/Users/luo_mac/Library/Android/sdk
#对应自己实际的证书路径和名字,在这里由于签名文件是放在app目录下,因为没有写绝对路径。
keystroe_storeFile=chuangke.key
keystroe_storePassword=123456
keystroe_keyAlias=chuangke
keystroe_keyPassword=123456

看完build.gradle和local.properties的具体内容之后,我们再来挑选几个地方来具体说一下。

一. signingConfigs

在signingConfigs中主要是为打包配置签名文件具体信息的,第一种方式把签名文件的位置,storePassword ,keyAlias,keyPassword 等具体内容都直接写在其中,然后使用gradle进行打包,第二种是通过通过使用local.properties文件来间接加载签名文件的具体信息。一般我们更倾向于第二种方法,这样有助于保护我们的签名文件(在local.properties中不能有中文)。

二. productFlavors

不同渠道的设置基本都是在 productFlavors 里设置的,在里面想要添加多少个渠道都可以。

不同渠道app名称

manifestPlaceholders = [app_name: "@string/app_name"]

也可以修改app名称,通过resValue 我们可以在在 string.xml 里面添加了一个新的字段app_name,由于是添加,所以原来的string.xml 文件中不能存在app_name字段,否则会报错。
当然我们还可以添加布尔类型,还可以为color.xml、dimen.xml添加一些我们需要的字段。

修改app图标
当我们在productFlavors 中添加了不同渠道环境名称之后,我们还可以mian文件夹同层级中建立渠道对应的文件夹,并放入特定的图标文件,当然我们还可以放入其他资源文件,甚至AndroidManifest.xml都可以放入,Gradle在构建应用时,会优先使用flavor所属dataSet中的同名资源。所以,在flavor的dataSet中添加同名的资源文件,会覆盖默认的资源文件,这样就能达到不同环境不同软件图标的功能。

另外我们在添加签名之后,便可以直接使用命令打出不同渠道的apk包 ,命令是:

 ./gradlew assembleRelease

在使用这个命令时候,第一次也许会报一个-bash: ./gradlew: Permission denied的错误,可先使用如下命令

chmod +x gradlew

就可以编译出你想要的Apk包了,希望能帮到此时的你!!!

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

推荐阅读更多精彩内容