Gradle多版本/多环境打包

本文开发环境:

  • Android Studio 3.1.4 Build #AI-173.4907809, built on July 24, 2018
  • JRE: 1.8.0_152-release-1024-b02 amd64
  • JVM: OpenJDK 64-Bit Server VM by JetBrains s.r.o
  • Windows 10 10.0

一、概述

App开发过程中,基本都需要多个环境,比如开发环境develop,测试环境check,生产环境product。各个环境下,网络请求的url会有所区别,一般我们通过baseUrl进行切换。

  • 开发环境用于程序员开发和自测;
  • 测试环境用于测试人员测试使用,环境配置和生产环境完全相同;
  • 生产环境即正式环境,也就是用户所使用的环境。

每个环境下,app还可以分为debug版本和release版本。

  • debug版本下,apk无需混淆,可以多一些打印日志的操作。
  • release版本下,文件混淆,隐藏日志打印。

Android Studio中,多版本/多环境等需求都可以通过配置gradle文件来解决。

二、实践

debug和release版本的区分通过buildTypes

1. 新建一个demo工程,AS默认生成的gradle只有release版本。
defaultConfig {
    applicationId "com.allsunny.packagedemo"
    minSdkVersion 15
    targetSdkVersion 28
    versionCode 1
    versionName "1.0"
    testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
}
buildTypes {
    release {
        minifyEnabled false
        proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
    }
}

demo中的默认applicationId 为com.allsunny.packagedemo,我们知道,在Android系统中,同一个app只能安装一个,系统就是根据applicationId来判断是否为同一个apk。我们要想在一台手机中同时安装debug和release版本,就要修改applicationId 。

2.我们将其略加修改,添加混淆和debug版本。debug版本下增加字段applicationIdSuffix用来修改applicationId
    buildTypes {
        //调试版本,无混淆
        debug {
            //为debug版本的包名添加.debug后缀
            applicationIdSuffix ".debug"
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
        release {
            minifyEnabled true
            zipAlignEnabled true
            shrinkResources true
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
            signingConfig signingConfigs.config
        }
    }

修改完成后,我们可以通过选择Build Variant来选择不同的打包环境和打包版本,目前只有两个版本debug和release。如图所示:

1.png

我们选择release后编译打包。
因为我们现在有debug和release两个版本,release无法再使用默认的签名文件,所以我们要自己生成一个jks签名文件,release包使用新生成的正式签名文件来签名。否则会报错:

the apk for your currently selected variant(app-release-unsigned.apk)is not signed.
Please specity a signing configuration for this variant(release)

配置签名文件方案:https://blog.csdn.net/l_lhc/article/details/77963683
配置完成后,AS会自动在release{...}中生成 signingConfig signingConfigs.config。然后就可以正常编译打包了。至此,多版本的配置就完成了。接下来我们来看多环境的gradle配置。

环境的区分通过productFlavors

productFlavors {
    //开发环境
    develop {
        applicationIdSuffix ".dev"       //applicationId "com.allsunny.packagedemo.dev"
        buildConfigField("int", "ENV_TYPE", "1")
        manifestPlaceholders = ["app_name": "开发环境", "app_launcher_icon": "@mipmap/ic_launcher_dev"]
    }

    //生产环境
    product {
        buildConfigField("int", "ENV_TYPE", "2")
        manifestPlaceholders = ["app_name": "生产环境", "app_launcher_icon": "@mipmap/ic_launcher"]
    }
}

编译后如果报如下错误:

All flavors must now belong to a named flavor dimension. Learn more at https://d.android.com/r/tools/flavorDimensions-missing-error-message.html

则在android{...}中添加 flavorDimensions "default"

android {
    flavorDimensions "default"
    ......
    }

目前demo中只添加了开发环境和生产环境,开发者可以自主添加测试环境。我们在develop环境中增加了applicationIdSuffix ".dev" ,这样就可以在同一台手机中同时安装4个apk包了。分别是:

  • 开发环境debug版本,包名com.allsunny.packagedemo.dev.debug
  • 开发环境release版本,包名com.allsunny.packagedemo.dev
  • 生产环境debug版本,包名com.allsunny.packagedemo.debug
  • 生产环境debug版本,包名com.allsunny.packagedemo

buildConfigField表示在编译生成的BuildConfig文件当中添加字段属性“ENV_TYPE”,我们可以在代码当中根据BuildConfig.ENV_TYPE的值来判断apk是处于开发环境(1== BuildConfig.ENV_TYPE)还是生产环境(2==BuildConfig.ENV_TYPE)。

manifestPlaceholders中定义的属性字段会替换AndroidManifest当中的相关属性,我们目前替换了app名称和icon。在manifest文件中需做对应修改:

    <application
        android:allowBackup="true"
        android:icon="${app_launcher_icon}"
        android:label="${app_name}"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity android:name=".MainActivity"
            android:screenOrientation="portrait">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

编译后在Build Variant中可以看到可以生成4个apk版本了:

2.png

我们在页面中将包名和ENV_TYPE打印出来:

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        tvPackageName = findViewById(R.id.tv_package_name);
        tvPackageName.setText("packageName = " + getApplication().getPackageName() + "\n\n"
                + "ENV_TYPE = " + BuildConfig.ENV_TYPE);
    }

显示页面如图所示:


3.jpg
4.jpg
5.jpg

至此,我们就完成了多版本和多环境的gradle文件配置。

三、注意:

  1. 网上的第三方推送一般以按包名唯一区分,已上线的app有集成推送模块的,要根据不同包名申请多个账号。防止把测试的推送信息推送给正式用户。
  2. 微信的分享也是根据包名来进行验证的,所以测试分享模块时候,要将环境改为生产环境的release版本。
  3. 在代码中使用到provider的地方,也需要根据包名做对应的修改,比如:
        <provider
            android:name="android.support.v4.content.FileProvider"
            android:authorities="${applicationId}.fileprovider"
            android:exported="false"
            android:grantUriPermissions="true">
            <meta-data
                android:name="android.support.FILE_PROVIDER_PATHS"
                android:resource="@xml/file_paths"/>

        </provider>
 Matisse.from(this)
     .choose(MimeType.ofImage())
     .showSingleMediaType(true)
     .countable(false)
     .capture(true)
     .captureStrategy(new CaptureStrategy(true, mContext.getPackageName() + ".fileprovider"))
     .maxSelectable(1)
     .thumbnailScale(0.85f)
     .imageEngine(new GlideEngine())
     .forResult(REQUEST_CODE_CHOOSE);

四、demo下载地址:

https://download.csdn.net/download/akirah/10610665

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

推荐阅读更多精彩内容