多渠道打包

環(huán)境

OSX
AndroidStudio 1.0

多渠道設(shè)置

渠道號(hào)

以友盟SDK為例,打包多渠道:GooglePlay纯露,小米友盟代芜,360埠褪,豌豆莢應(yīng)用寶挤庇。
AndroidManifest.xml中加入渠道區(qū)分標(biāo)識(shí)

<meta-data 
    android:name="UMENG_CHANNEL"
    android:value="${UMENG_CHANNEL_VALUE}" />

然后在build.gradle(Module: app)中加入渠道打包替換對應(yīng)的UMENG_CHANNEL_VALUE代碼

// 渠道Flavors钞速,配置不同的渠道
    productFlavors {
        GooglePlay {}
        xiaomi {}
        umeng {}
        qihu360 {}
        wandoujia {}
        yingyongbao {}
        //其他...
    }

    // 批量配置渠道
    productFlavors.all {
        flavor -> flavor.manifestPlaceholders = [UMENG_CHANNEL_VALUE: name]
    }

apk名字

我們還可以指定不同渠道號(hào)生成的apk的名字,這樣方便打包出來區(qū)別哪個(gè)apk是對應(yīng)哪個(gè)渠道的嫡秕。以下的例子生成的命名格式 app_v(版本號(hào))_打包時(shí)間_渠道號(hào).apk

android{

        applicationVariants.all { variant ->
            variant.outputs.each { output ->
                def outputFile = output.outputFile
                if (outputFile != null && outputFile.name.endsWith('.apk')) {
                    File outputDirectory = new File(outputFile.parent);
                    def fileName
                    if (variant.buildType.name == "release") {
                        fileName = "app_v${defaultConfig.versionName}_${packageTime()}_${variant.productFlavors[0].name}.apk"
                    } else {
                        fileName = "app_v${defaultConfig.versionName}_${packageTime()}_beta.apk"
                    }
                    output.outputFile = new File(outputDirectory, fileName)
                }
            }
        }

    }

打包

簽名文件

生成簽名文件可用命令行生成渴语,也可以直接用AndroidStudio的Build -> Generate signed apk -> create new 生成新證書即可。然后為了方便昆咽,這里我把證書放到 項(xiàng)目 -> app 目錄下驾凶。

簽名配置

gradle支持直接簽名打包,只需要設(shè)置一下證書的路徑和對應(yīng)密碼一鍵打包出正式可以發(fā)布的apk掷酗。
signingConfigs里面寫上對應(yīng)的storeFile调违,storePasswordkeyAlias泻轰,keyPassword
一般地技肩,為了保護(hù)簽名文件,這些信息不應(yīng)該寫入到版本庫中浮声,我這里把它們寫在local.properties中然后在版本庫中排除這個(gè)文件虚婿。
//獲取local.properties的內(nèi)容

//這里是讀取local.properties文件殖告,提供給下方代碼用來提取keystroe_storeFile等key的值
Properties properties = new Properties()
properties.load(project.rootProject.file('local.properties').newDataInputStream())
signingConfigs {

        release {
            // relase簽名
            storeFile file(properties.getProperty("keystroe_storeFile"))
            storePassword properties.getProperty("keystroe_storePassword")
            keyAlias properties.getProperty("keystroe_keyAlias")
            keyPassword properties.getProperty("keystroe_keyPassword")
        }
    }

local.properties文件中加入

keystroe_storeFile=keystore.jks  //對應(yīng)自己實(shí)際的證書路徑和名字,因?yàn)槲疑厦嫣岬?把證書放在 項(xiàng)目的app目錄下雳锋,所以不用寫絕對路徑黄绩。
keystroe_storePassword=123456
keystroe_keyAlias=alias
keystroe_keyPassword=123456

打包apk

在終端窗口,或者可以使用AndroidStudio工具欄下面提供的終端 Terminal 玷过,cd 到 項(xiàng)目根目錄下執(zhí)行:

// 打包出上面所有渠道apk
./gradlew build
// 下面這行例子是單獨(dú)打包wandoujia渠道的apk
// ./gradlew assembleWandoujia

對應(yīng)渠道的apk就會(huì)自動(dòng)在 項(xiàng)目/app/build/outputs/apk/ 目錄下按照上面指定的命名格式生成了爽丹。

產(chǎn)品定制

ApplicationId,版本號(hào)

Android 應(yīng)用都有自己的包名辛蚊。包名是設(shè)備上每個(gè)應(yīng)用程序的唯一標(biāo)識(shí)粤蝎,同樣也是在各個(gè)下載平臺(tái)的唯一標(biāo)識(shí)。就是說袋马,假如你已經(jīng)使用某個(gè)包名來發(fā)布應(yīng)用初澎,就不能再去改變應(yīng)用的包名,因?yàn)檫@樣做會(huì)導(dǎo)致你的應(yīng)用被視為一個(gè)全新的應(yīng)用虑凛,你現(xiàn)有的用戶也不會(huì)收到應(yīng)用的更新通知碑宴。
有時(shí)候我們需要發(fā)布不同的版本,例如 pro桑谍,hd 版本延柠,支持用戶可以下載安裝不同的版本。那么我們需要設(shè)置不同的ApplicationId和對應(yīng)的版本號(hào)锣披, 同時(shí)要與 PackageName 解耦合贞间。

  • 代碼中引用的 R 類要保持不變;

  • 在構(gòu)建不同版本的應(yīng)用時(shí)雹仿,對應(yīng)的(引用了 R 的) .java 源文件也不能改動(dòng)增热。

那么我們只需要在productFlavors對應(yīng)的渠道中指定applicationIdversionCode,versionName胧辽,例我們指定GooglePlayapplicationId

productFlavors {
        GooglePlay {
            //指定這個(gè)渠道的版本號(hào)
            versionCode 2
            versionName "2.0"
            //指定區(qū)別于其他渠道的 applicationId
            applicationId "com.bigkoo.gradledemo.hd"
        }
        xiaomi {}
        umeng {}
        qihu360 {}
        wandoujia {}
        yingyongbao {}
        //其他...
    }

BuildConfig

Gradle會(huì)在generateSources階段為flavor生成一個(gè)BuildConfig.java文件峻仇。BuildConfig類默認(rèn)提供了一些常量字段,比如應(yīng)用的版本名(VERSION_NAME)票顾,應(yīng)用的包名(PACKAGE_NAME)等础浮。更強(qiáng)大的是帆调,開發(fā)者還可以添加自定義的一些字段奠骄。下面的示例假設(shè)debug版開啟LOG功能,使用test的api番刊,而發(fā)布版則使用不開啟LOG和使用發(fā)布時(shí)的api

buildTypes {
        debug {
            // debug模式下含鳞,顯示log
            buildConfigField("boolean", "LOG_DEBUG", "true")
            buildConfigField ("String", "API_HOST", "\"http://api.test.com\"")//API Host
        }
        release {
            // release模式下,不顯示log
            buildConfigField("boolean", "LOG_DEBUG", "false")
            buildConfigField("String", "API_HOST", "\"http://api.release.com\"")//API Host
        }
    }

那么代碼中就可以使用 BuildConfig.LOG_DEBUG 和 BuildConfig.API_HOST 了芹务。
甚至可以在productFlavors對應(yīng)的渠道號(hào)進(jìn)行區(qū)別蝉绷,例如豌豆莢版默認(rèn)禁止版本自動(dòng)更新:

android {
    defaultConfig {
        buildConfigField "boolean", "AUTO_UPDATES", "true"
    }

    productFlavors {
        wandoujia {
            buildConfigField "boolean", "AUTO_UPDATES", "false"
        }        
    }

}

資源

通常對于不同渠道鸭廷,我們會(huì)區(qū)別不同的資源。例如我們一款應(yīng)用需要在360發(fā)布熔吗,而應(yīng)用圖標(biāo)和歡迎界面要一個(gè)360標(biāo)志的圖辆床,那么這個(gè)時(shí)候就需要按渠道打包對應(yīng)的應(yīng)用圖標(biāo)和歡迎圖片了。Gradle在構(gòu)建應(yīng)用時(shí)桅狠,會(huì)優(yōu)先使用flavor所屬dataSet中的同名資源讼载。所以,在flavordataSet中添加同名的字符串資源中跌,以覆蓋默認(rèn)的資源咨堤。
上面我們已經(jīng)有針對360的渠道了,就是qihu360漩符,我們只需要在 app/src/ 目錄下添加渠道對應(yīng)的文件夾qihu360一喘,然后覆蓋對應(yīng)要覆蓋的內(nèi)容。下面是定制應(yīng)用圖標(biāo)的步驟:

  • 添加qihu360文件夾嗜暴,那么在 app/src/ 目錄下面就有 main , androidTest , qihu360 這三個(gè)文件夾了凸克。main 目錄是通用正常渠道包目錄,qihu360是我們需要定制資源的渠道包目錄闷沥。

  • 仿main的目錄触徐,添加 res/drawable/ic_launcher.png 圖片以覆蓋對應(yīng)在 main里面的res/drawable/ic_launcher.png

通過以上例子,舉一反三狐赡。定制其他資源撞鹉,包括strings.xmlstyles.xml 甚至AndroidManifest.xml 也都是可以的颖侄。

第三方庫

有些渠道需要加入廣告鸟雏,應(yīng)用墻推薦,而有些則不上廣告览祖,我們常常也會(huì)遇到這樣的問題吧孝鹊。那么現(xiàn)在來說說怎么對于第三方庫進(jìn)行渠道區(qū)分打包。
這里以我的開源項(xiàng)目 為例展蒂,其他庫或廣告SDK同理:

dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
    compile 'com.android.support:appcompat-v7:21.0.3'
    //參與編譯but不參與打包
    provided 'com.bigkoo:alertview:1.0.1'
    //指定qihu360這個(gè)渠道可以打包這個(gè)庫
    qihu360Compile 'com.bigkoo:alertview:1.0.1'
}

然后在代碼中進(jìn)行反射判斷是否有這個(gè)庫存在又活,如果有就使用,沒有就不使用锰悼。(或者用上面提及的BuildConfig方式設(shè)置一個(gè)渠道常量來判斷也可以

public class MainActivity extends Activity {

    private boolean useAlertView;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        try {
            Class.forName("com.bigkoo.alertview.AlertView");
            useAlertView = true;
        } catch (ClassNotFoundException ignored) {

        }
    }

    public void showAlertView(View view) {
        if(useAlertView) {
            new AlertView("標(biāo)題", "內(nèi)容", null, new String[]{"確定"}, null, this, AlertView.Style.Alert, null).show();
        }
    }
}

總結(jié)

常用的多渠道打包方式已經(jīng)介紹完了柳骄,基本能滿足日常大部分多渠道打包開發(fā)使用。如果你想更深入了解箕般,請看Groovy耐薯,自己來定制一些任務(wù)。

本文參考

Gradle
美團(tuán)Android自動(dòng)化之旅—適配渠道包
安卓集成發(fā)布詳解(二)

源碼

本文例子的源碼放在我的Github上了,地址:GradleDemo (PS:例子為了提供完整的演示曲初,沒有在.gitigonore里面加入 /local.properties 排除体谒,實(shí)際是要加入的,另外簽名文件也一并附上了臼婆,也實(shí)際是需要排除的抒痒。)

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市颁褂,隨后出現(xiàn)的幾起案子评汰,更是在濱河造成了極大的恐慌,老刑警劉巖痢虹,帶你破解...
    沈念sama閱讀 217,277評論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件被去,死亡現(xiàn)場離奇詭異,居然都是意外死亡奖唯,警方通過查閱死者的電腦和手機(jī)惨缆,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,689評論 3 393
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來丰捷,“玉大人坯墨,你說我怎么就攤上這事〔⊥” “怎么了捣染?”我有些...
    開封第一講書人閱讀 163,624評論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長停巷。 經(jīng)常有香客問我耍攘,道長,這世上最難降的妖魔是什么畔勤? 我笑而不...
    開封第一講書人閱讀 58,356評論 1 293
  • 正文 為了忘掉前任蕾各,我火速辦了婚禮,結(jié)果婚禮上庆揪,老公的妹妹穿的比我還像新娘式曲。我一直安慰自己,他們只是感情好缸榛,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,402評論 6 392
  • 文/花漫 我一把揭開白布吝羞。 她就那樣靜靜地躺著,像睡著了一般内颗。 火紅的嫁衣襯著肌膚如雪钧排。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,292評論 1 301
  • 那天起暮,我揣著相機(jī)與錄音卖氨,去河邊找鬼。 笑死负懦,一個(gè)胖子當(dāng)著我的面吹牛筒捺,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播纸厉,決...
    沈念sama閱讀 40,135評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼系吭,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了颗品?” 一聲冷哼從身側(cè)響起肯尺,我...
    開封第一講書人閱讀 38,992評論 0 275
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎躯枢,沒想到半個(gè)月后则吟,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,429評論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡锄蹂,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,636評論 3 334
  • 正文 我和宋清朗相戀三年氓仲,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片得糜。...
    茶點(diǎn)故事閱讀 39,785評論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡敬扛,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出朝抖,到底是詐尸還是另有隱情啥箭,我是刑警寧澤,帶...
    沈念sama閱讀 35,492評論 5 345
  • 正文 年R本政府宣布治宣,位于F島的核電站急侥,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏侮邀。R本人自食惡果不足惜缆巧,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,092評論 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望豌拙。 院中可真熱鬧陕悬,春花似錦、人聲如沸按傅。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,723評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽唯绍。三九已至拼岳,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間况芒,已是汗流浹背惜纸。 一陣腳步聲響...
    開封第一講書人閱讀 32,858評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人耐版。 一個(gè)月前我還...
    沈念sama閱讀 47,891評論 2 370
  • 正文 我出身青樓祠够,卻偏偏與公主長得像,于是被迫代替她去往敵國和親粪牲。 傳聞我的和親對象是個(gè)殘疾皇子古瓤,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,713評論 2 354

推薦閱讀更多精彩內(nèi)容

  • 目錄一、Python打包及優(yōu)化(美團(tuán)多渠道打包)二腺阳、Gradle打包三落君、其他打包方案:修改Zip文件的commen...
    守望君閱讀 5,689評論 4 17
  • Android多渠道打包 概述 每當(dāng)發(fā)新版本時(shí),Android客戶端會(huì)被分發(fā)到各個(gè)應(yīng)用市場亭引,比如豌豆莢绎速,360手機(jī)...
    礪雪凝霜閱讀 2,133評論 2 11
  • 寫在前面的話 公司之前使用Ant打包的,一個(gè)包平均要10分鐘焙蚓,三四個(gè)包下來朝氓,一個(gè)小時(shí)過去了,作為一名有追求的程序員...
    三少爺?shù)拇a閱讀 2,950評論 1 7
  • 今天看了@Conditional,自己根據(jù)以下文章練了下主届,根據(jù)自己的理解操作的 轉(zhuǎn)載出處:http://wisel...
    zhuyuansj閱讀 952評論 0 0
  • 我想告訴路過的風(fēng) 我想告訴飄過的云 我想告訴遇到的每個(gè)人 我喜歡你 我想在額頭刻上你的名字 讓每個(gè)看到我的人 都知...
    藍(lán)銫冽痕閱讀 254評論 0 0