Android使用Gradle玩轉多渠道多包名打包

寫這篇文章主要是因為,公司的項目對打包有多重需求,有哪些需求呢?
1.多渠道,這是最基本的;
2.分為3個版本(內地版,海外版,精簡版),每個版本包名不同(這就意味著第三方sdk的各種key都不一樣),且logo,部分圖標也不一樣;
3.開發(fā)版本的區(qū)別,分為debug版,pre預覽版,release正式版;
4.開發(fā)版本的區(qū)別要通過app名稱直接體現(xiàn)在桌面上,即apk安裝后,app名稱直接是XXdebug版,XXrelease版本

現(xiàn)在我們就分別來實現(xiàn)以上的需求

一.多渠道打包

gradle的productFlavors用來配置渠道,這里主要介紹一下友盟的多渠道打包配置

  1. 在AndroidManifest.xml中做如下配置
<meta-data
           android:name="UMENG_CHANNEL"
           android:value="${UMENG_CHANNEL_VALUE}" />

${...}這個占位符很重要,下面我們動態(tài)配置一些屬性的時候都會用到這個占位符

  1. 在項目app這個module下的gradle中配置渠道,注意這個productFlavors是配置在android下的
//配置多渠道
    flavorDimensions "default"
    productFlavors {
        wandoujia {dimension "default"}
        _360 {dimension "default"}
        baidu {dimension "default"}
        xiaomi {dimension "default"}
        tencent {dimension "default"}
        taobao {dimension "default"}
    }

    productFlavors.all { flavor ->
        flavor.manifestPlaceholders = [UMENG_CHANNEL_VALUE: name]
    }
  1. 如上配置后,在AndroidStudio的Build->Select Build Variants ,可以看到每個渠道都有debug和release兩個版本


    多渠道.png
  • 4 多版本apk安裝在同一手機上,也就是打多版本
    這是看到了這位大神的文章,覺得講的比我寫的更詳細,下面部分就直接使用大神文章,謝謝作者
    這種情況只需要我們提供不同包名的apk即可完成。因為只要應用包名不一樣即使簽名信息一樣還是可以同時安裝在同一臺手機上的,因此我們應該在打包成apk時修改應用的包名就可以達到目的啦碉怔。接下來我們進入實際操作過程徐勃。這里我們先介紹一個知識點,請直接看下圖:
    image.png

當然從截圖也可以看出礼患,配置多apk打包和上一篇文章配置多渠道打包是一樣的,都是在productFlavors中配置的是钥。如上圖,我們在productFlavors中配置了兩種flavor的apk信息一種是Beta版缅叠,一種是Releases版悄泥,同時每個flavor中我們都重新配置applicationId這個屬性,通過這個屬性我們就可以使打包出來的apk包名產生對應的變化啦肤粱。至于為什么重新配置了applicationId就行呢弹囚,原因圖已經說明啦,就是因為defaultConfig是Beta版和Releases版flavor的基礎配置领曼,只要我們重寫了applicationId這個屬性就會覆蓋defaultConfig中相對應屬性的信息鸥鹉,從而使打包出來的兩種apk的包名不一樣,達到在同一臺手機上安裝的目的庶骄。那么applicationId又是什么呢毁渗?看下圖(因此我們更改其實就是package屬性)


image.png
image.png

比如說不同版本要使用不同的icon,這時該如何做呢瓢姻?實際上還是在productFlavors的每個flavor中通過manifestPlaceholders屬性配置即可祝蝠,manifestPlaceholders是一個類似HashMap的容器,因此在manifestPlaceholders可以配置多個屬性幻碱,以便在AndroidManifest.xm中使用绎狭,比如我們需要為每種版本的apk替換特定的icon和appName這時我們可以這樣如下配置:


image.png

然后在AndroidManifest.xm中這樣使用即可:


image.png
   defaultConfig {
        applicationId "com.zejian.multi_versionapk"
        minSdkVersion 10
        targetSdkVersion 23
        versionCode 1
        versionName "1.0"
    }
    buildTypes {
        release {
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
            signingConfig signingConfigs.debug4zj
            minifyEnabled true
            zipAlignEnabled true
        }
    }
    //配置多版本的apk
    productFlavors{
        Beta{
            applicationId "com.zejian.multi_versionapk.beta"
            manifestPlaceholders = [app_name:"multi_versionapk.beta" ,icon: "@mipmap/ic_launcher_beta"]
            //在java代碼中具體的使用方式為:context.getResources().getString(R.string.strKey);
            resValue("string" , "strKey","beta版本")
        }
        Releases{
            applicationId "com.zejian.multi_versionapk.release"
            manifestPlaceholders = [app_name:"multi_versionapk.release",icon: "@mipmap/ic_launcher_releases"]
            resValue("string" , "strKey","release版本")
        }
    }
}
多版本.png

同時,我們Generate signed APK就可以打出release和debug的每個版本和每個渠道的包


打包的選項.png

至此,我們就可以通過Build Variants來控制當前的運行環(huán)境,來決定當前的包是屬于哪個版本和哪個渠道

二. 多渠道包跟多版本包不同的內容,如何來區(qū)分,也就是文章開頭第二條中的icon,logo,包名等信息不同時候如何來區(qū)別對待,那就要用到manifestPlaceholders了,文章上面說過,我們使用${...}占位符能夠動態(tài)替換AndroidManitest里面的很多東西,如何操作請往下看
wandoujia {
            dimension "default"
            manifestPlaceholders = [
                    applicationId :"com.app.test",
                    app_name     : "@string/AppName",
                    icon         : "@string/ic_launcher",
                    app_key      : "1234567",
                    umeng_channel: "豌豆莢"
            ]
        }
 wandoujia_oas {
            dimension "default"
            manifestPlaceholders = [
                    applicationId :"com.app.oas",
                    app_name     : "@string/AppNameOas",
                    icon         : "@string/ic_launcher",
                    app_key      : "910JQKA",
                    umeng_channel: "豌豆莢海外版"
            ]
        }
<application
        android:allowBackup="false"
        android:icon="${icon}"
        android:label="${app_name}"
        android:persistent="true"
        android:supportsRtl="true"
        android:theme="@style/AppTheme"
        tools:replace="android:allowBackup,android:label, android:icon, android:theme">

這樣第三方SDK的不同key都可以采用占位符來動態(tài)替換,就像上面,當我們打海外版包時,就會將app_key和logo替換成另一套

三. 針對debug版本和release版本一些控制,就要用到 buildConfigField 了,buildConfigField 能夠在debug和release中生成不同的BuildConfig,我們在開發(fā)中的是否需要打印日志的控制就可以使用它
buildTypes {
        release {
            minifyEnabled false
            debuggable false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
            buildConfigField("boolean","show_log","false")
        }

        //預覽版
        pre {
            minifyEnabled false
            debuggable false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
            buildConfigField("boolean","show_log","true")
        }

        debug {
            minifyEnabled false
            debuggable true
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
            buildConfigField("boolean","show_log","true")
        }
    }

配置之后我們得到的BuildConfig如下,在代碼中使用直接BuildConfig.xxx就可以

public final class BuildConfig {
  public static final boolean DEBUG = false;
  public static final String APPLICATION_ID = "kotlin.app.com.gradledemo";
  public static final String BUILD_TYPE = "release";
  public static final String FLAVOR = "baidu";
  public static final int VERSION_CODE = 1;
  public static final String VERSION_NAME = "1.0";
  // Fields from build type: release
  public static final boolean show_log = false;
}

除了日志開關,其他用的最多的地方還有url環(huán)境的切換,比如debug版本一般我們會用內網(wǎng)的url,那么release版本就需要用生產環(huán)境的url

四. 要實現(xiàn)開篇的不同版本的apk名稱不一樣,就需要用到resValue了,它能夠定義資源,并且可以在debug和release等不同版本中來分別定義,例如resValue "string" 就是字符串資源,可以用R.String 來引用對應的字符串資源
//在debug下設置如下
resValue "string","AppName","測試DEV"
resValue "string","AppNameOas","測試海外版DEV"
resValue "string","AppNameSimple","測試1精簡版DEV"

這時候一編譯,就會自動在R.String下生成AppName,AppNameOas,AppNameSimple三個字符串,通過R.String.xxx就可以引用到;
注意:需要將之前values下string下的appName刪除,否則會報資源重復異常

五. 全局配置文件

project的build.gradle中的ext可以為各位module進行全局配置參數(shù)褥傍,防止各個module之間的不統(tǒng)一儡嘶,不可控。而且當我們升級sdk恍风、build tool蹦狂、target sdk等,幾個module都要更改朋贬,非常的麻煩凯楔。
在項目根目錄建立gradleConfig,然后

ext {
    //統(tǒng)一管理依賴版本
    android = [
            compileSdkVersion: 25,
            buildToolsVersion: '25.0.2',
            applicationId    : "com.test.xxx",
            minSdkVersion    : 17,
            targetSdkVersion : 24,
            versionCode      : 2
            versionName      : "0.1"

    ]

    def dependVersion = [
            support: "25.1.0"
    ]
    dependencies = [
            "appcompat-v7"   : "com.android.support:appcompat-v7:${dependVersion.support}",
            "cardview-v7"    : "com.android.support:cardview-v7:${dependVersion.support}",
            "recyclerview-v7": "com.android.support:recyclerview-v7:${dependVersion.support}",
            "design"         : "com.android.support:design:${dependVersion.support}",
            "support-v4"     : "com.android.support:support-v4:${dependVersion.support}"
    ]
}

然后在每個module中引用

android {

    compileSdkVersion rootProject.ext.compileSdkVersion

    buildToolsVersion rootProject.ext.buildToolsVersion

   defaultConfig {

      applicationId "com.xxx.xxx"

      minSdkVersion rootProject.ext.minSdkVersion

      targetSdkVersion rootProject.ext.targetSdkVersion

      versionCode rootProject.ext.versionCode

      versionName rootProject.ext.versionName
    }
}
六. module 調整目錄結構sourceSets

默認情況下,java文件和resource文件分別在src/main/java和src/main/res目錄下锦募,在build.gradle文件摆屯,andorid{}里面添加下面的代碼,便可以將java文件和resource文件放到src/java和src/resources目錄下糠亩。

sourceSets {
   main {
      java {
          srcDir 'src/java'
      }
      resources {
        srcDir 'src/resources'
     }
   }
}

簡便寫法

sourceSets {
   min.java.srcDirs = ['src/java']
   min.resources.srcDirs = ['src/resources']
}
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末虐骑,一起剝皮案震驚了整個濱河市准验,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌廷没,老刑警劉巖糊饱,帶你破解...
    沈念sama閱讀 206,013評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異颠黎,居然都是意外死亡另锋,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,205評論 2 382
  • 文/潘曉璐 我一進店門盏缤,熙熙樓的掌柜王于貴愁眉苦臉地迎上來砰蠢,“玉大人,你說我怎么就攤上這事唉铜√ú眨” “怎么了?”我有些...
    開封第一講書人閱讀 152,370評論 0 342
  • 文/不壞的土叔 我叫張陵潭流,是天一觀的道長竞惋。 經常有香客問我,道長灰嫉,這世上最難降的妖魔是什么拆宛? 我笑而不...
    開封第一講書人閱讀 55,168評論 1 278
  • 正文 為了忘掉前任,我火速辦了婚禮讼撒,結果婚禮上浑厚,老公的妹妹穿的比我還像新娘。我一直安慰自己根盒,他們只是感情好钳幅,可當我...
    茶點故事閱讀 64,153評論 5 371
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著炎滞,像睡著了一般敢艰。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上册赛,一...
    開封第一講書人閱讀 48,954評論 1 283
  • 那天钠导,我揣著相機與錄音,去河邊找鬼森瘪。 笑死牡属,一個胖子當著我的面吹牛,可吹牛的內容都是我干的扼睬。 我是一名探鬼主播逮栅,決...
    沈念sama閱讀 38,271評論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了证芭?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 36,916評論 0 259
  • 序言:老撾萬榮一對情侶失蹤担映,失蹤者是張志新(化名)和其女友劉穎废士,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體蝇完,經...
    沈念sama閱讀 43,382評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡官硝,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 35,877評論 2 323
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了短蜕。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片氢架。...
    茶點故事閱讀 37,989評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖朋魔,靈堂內的尸體忽然破棺而出岖研,到底是詐尸還是另有隱情,我是刑警寧澤警检,帶...
    沈念sama閱讀 33,624評論 4 322
  • 正文 年R本政府宣布孙援,位于F島的核電站,受9級特大地震影響扇雕,放射性物質發(fā)生泄漏拓售。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 39,209評論 3 307
  • 文/蒙蒙 一镶奉、第九天 我趴在偏房一處隱蔽的房頂上張望础淤。 院中可真熱鬧,春花似錦哨苛、人聲如沸鸽凶。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,199評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽吱瘩。三九已至,卻和暖如春迹缀,著一層夾襖步出監(jiān)牢的瞬間使碾,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,418評論 1 260
  • 我被黑心中介騙來泰國打工祝懂, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留票摇,地道東北人。 一個月前我還...
    沈念sama閱讀 45,401評論 2 352
  • 正文 我出身青樓砚蓬,卻偏偏與公主長得像矢门,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 42,700評論 2 345

推薦閱讀更多精彩內容

  • Spring Cloud為開發(fā)人員提供了快速構建分布式系統(tǒng)中一些常見模式的工具(例如配置管理祟剔,服務發(fā)現(xiàn)隔躲,斷路器,智...
    卡卡羅2017閱讀 134,599評論 18 139
  • 1.介紹 如果你正在查閱build.gradle文件的所有可選項物延,請點擊這里進行查閱:DSL參考 1.1新構建系統(tǒng)...
    Chuckiefan閱讀 12,115評論 8 72
  • 轉載注明出處:http://www.reibang.com/p/5255b100930e 0. 前言 完全由個人翻...
    王三的貓阿德閱讀 2,501評論 0 4
  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 171,498評論 25 707
  • 1.有資本 比如有不動產可以出租宣旱,有資金可以儲蓄理財。 2.有一個運營良好的公司 自己不上班叛薯,也就是要一個可靠的外...
    步履如菲閱讀 566評論 0 50