偷偷摘套内射激情视频,久久精品99国产国产精,中文字幕无线乱码人妻,中文在线中文a,性爽19p

vivo官網(wǎng)App模塊化開(kāi)發(fā)方案-ModularDevTool

移動(dòng)開(kāi)發(fā)
本文主要講述了Android客戶(hù)端模塊化開(kāi)發(fā)的痛點(diǎn)及解決方案,詳細(xì)講解了方案的實(shí)現(xiàn)思路和具體實(shí)現(xiàn)方法。

說(shuō)明:本工具基于vivo互聯(lián)網(wǎng)客戶(hù)端團(tuán)隊(duì)內(nèi)部開(kāi)源的編譯管理工具開(kāi)發(fā)。

一、背景

現(xiàn)在客戶(hù)端的業(yè)務(wù)越來(lái)越多,大部分客戶(hù)端工程都采用模塊化的開(kāi)發(fā)模式,也就是根據(jù)業(yè)務(wù)分成多個(gè)模塊進(jìn)行開(kāi)發(fā),提高團(tuán)隊(duì)效率。例如我們vivo官網(wǎng)現(xiàn)在的整體架構(gòu)如下圖,分為13個(gè)模塊,每個(gè)模塊是一個(gè)獨(dú)立代碼倉(cāng)。

(注:為什么這么分,可以參考之前的一篇文章《??Android模塊化開(kāi)發(fā)實(shí)踐???》)


圖片


二、痛點(diǎn)

完全隔離的代碼倉(cāng),使每個(gè)模塊更獨(dú)立,更易于代碼管理,但也帶來(lái)了一些問(wèn)題

圖片

1、開(kāi)發(fā)階段,子倉(cāng)開(kāi)發(fā)以及集成開(kāi)發(fā)調(diào)試,操作麻煩、易出錯(cuò)、難跟蹤回溯

1.1、當(dāng)開(kāi)發(fā)時(shí)涉及的模塊較多時(shí),需要手動(dòng)一個(gè)一個(gè)拉代碼,多個(gè)子倉(cāng)的代碼操作非常麻煩,并且需要打開(kāi)多個(gè)AndroidStudio進(jìn)行開(kāi)發(fā);

1.2、子倉(cāng)集成到主倉(cāng)開(kāi)發(fā)調(diào)試,有兩種方式,但是都有比較大的缺點(diǎn):

(1)方式1,子倉(cāng)通過(guò)maven依賴(lài),這種方式需要不斷的發(fā)布子倉(cāng)的snapshot,主倉(cāng)再更新snapshot,效率較低;

(2)方式2,子倉(cāng)通過(guò)代碼依賴(lài),也就是需要在主倉(cāng)的settings.gradle中,手動(dòng)include拉到本地的子倉(cāng)代碼,然后在build.gradle中配置dependencies,配置繁瑣,容易出錯(cuò);

1.3、主倉(cāng)對(duì)子倉(cāng)的依賴(lài),如果是部分maven依賴(lài)、部分代碼依賴(lài),容易出現(xiàn)代碼沖突;

1.4、apk集成的子模塊aar和代碼,沒(méi)有對(duì)應(yīng)關(guān)系,排查問(wèn)題時(shí)很難回溯。

2、版本發(fā)布階段,流程繁瑣,過(guò)多重復(fù)勞動(dòng),流程如下:

2.1、逐個(gè)修改子倉(cāng)的版本,指定snapshot或release;

2.2、每個(gè)子倉(cāng)需要提交修改版本號(hào)的代碼到git;

2.3、每個(gè)子倉(cāng)都要手動(dòng)觸發(fā)發(fā)布maven倉(cāng);

2.4、更新主倉(cāng)對(duì)子倉(cāng)依賴(lài)的版本;

2.5、構(gòu)建Apk;

2.6、如果用持續(xù)集成系統(tǒng)CI,則每個(gè)子倉(cāng)都需要配置一個(gè)項(xiàng)目,再逐個(gè)啟動(dòng)子倉(cāng)的編譯,等子倉(cāng)全部編譯完再啟動(dòng)主倉(cāng)編譯。

三、方案

針對(duì)上述問(wèn)題,我們優(yōu)化的思路也很明確了,就是以自動(dòng)化的方式解決繁瑣和重復(fù)的操作。最終開(kāi)發(fā)了ModularDevTool,實(shí)現(xiàn)以下功能:

圖片

1、開(kāi)發(fā)階段

1.1、在主倉(cāng)中,管理所有子倉(cāng)代碼(拉代碼、切分支及其他git操作),管理子倉(cāng)相關(guān)信息(代碼倉(cāng)路徑、分支、版本等);

1.2、只需要打開(kāi)一個(gè)AS工程,即可進(jìn)行所有倉(cāng)的代碼開(kāi)發(fā);

1.3、對(duì)子倉(cāng)的兩種依賴(lài)方式(代碼依賴(lài)和maven依賴(lài))一鍵切換,支持混合依賴(lài)(即部分倉(cāng)代碼依賴(lài),部分倉(cāng)maven依賴(lài));

1.4、編譯時(shí)輸出子模塊的版本及對(duì)應(yīng)commitid,便于回溯跟蹤代碼。

2、版本發(fā)布階段

2.1、只需要在主倉(cāng)修改子倉(cāng)版本號(hào),子倉(cāng)無(wú)需修改,省去子倉(cāng)代碼修改和提交代碼過(guò)程;

2.2、CI上只要配一個(gè)主倉(cāng)項(xiàng)目,實(shí)現(xiàn)一鍵編譯,包括子倉(cāng)編譯aar(按依賴(lài)關(guān)系順序編譯)、上傳maven、編apk;

2.3、CI上支持3種編譯模式:

  • OnlyApp:即只編譯主倉(cāng)代碼生成apk(前提是子模塊已發(fā)布maven);
  • publishSnapshot:即子倉(cāng)編譯上傳snapshot版本,然后編譯主倉(cāng)生成apk;
  • publishRelease:即子倉(cāng)編譯上傳release版本,然后編譯主倉(cāng)生成apk。

四、ModularDevTool概覽

工具采用了shell腳本+gradle插件的方式實(shí)現(xiàn)的。

首先看下工程目錄概覽


圖片


1、submodules目錄是用來(lái)存放子倉(cāng)代碼的,子倉(cāng)代碼就是正常的工程結(jié)構(gòu),submodules目錄如下圖:

圖片

2、repositories.xml文件是用來(lái)配置子倉(cāng)信息的,包括模塊名、代碼倉(cāng)、分支、版本等,具體內(nèi)容如下:

<?xml versinotallow="1.0" encoding="utf-8" ?>
<repositories>
<!-- 一個(gè)repository表示一個(gè)倉(cāng)庫(kù),一個(gè)倉(cāng)庫(kù)下可能會(huì)有多個(gè)module -->
<repository>
<!-- 倉(cāng)庫(kù)名稱(chēng),可以隨意定義,主要用于本地快速識(shí)別 -->
<name>lib模塊</name>
<!-- 上傳至maven時(shí)的groupid -->
<group>com.vivo.space.lib</group>
<!-- 配置倉(cāng)庫(kù)中的所有子模塊,如果多個(gè)module就添加多個(gè)module標(biāo)簽 -->
<modules>
<module>
<!-- 上傳至maven時(shí)的artifactid -->
<artifactid>vivospace_lib</artifactid>
<!-- 上傳至maven時(shí)的版本號(hào) -->
<version>5.9.8.0-SNAPSHOT</version>
<!-- 編譯順序優(yōu)先級(jí),越小優(yōu)先級(jí)越高 -->
<priority>0</priority>
</module>
</modules>
<!-- 注意倉(cāng)庫(kù)地址中的個(gè)人ssh名稱(chēng)要使用$user占位符代替 -->
<repo>ssh://$user@smartgit:xxxx/VivoCode/xxxx_lib</repo>
<!-- 開(kāi)發(fā)分支,腳本用來(lái)自動(dòng)切換到該分支 -->
<devbranch>feature_5.9.0.0_xxx_dev</devbranch>
<!-- 打release包時(shí)必須強(qiáng)制指定commitId,保證取到指定代碼 -->
<commitid>cbd4xxxxxx69d1</commitid>
</repository>
<!-- 多個(gè)倉(cāng)庫(kù)就添加多個(gè)repository -->
...
</repositories>

3、vsub.sh腳本是工具各種功能的入口,比如:

  • ./vsub.sh sync:拉取所有子模塊代碼,代碼存放在主工程下的submodules目錄中
  • ./vsub.sh publish:一鍵編譯所有子倉(cāng),并發(fā)布aar到maven

4、subbuild目錄用來(lái)輸出子倉(cāng)的git提交記錄,subError目錄用來(lái)輸出子倉(cāng)編譯異常時(shí)的log。

五、關(guān)鍵功能實(shí)現(xiàn)

ModularDevTool主要功能分為兩類(lèi),一類(lèi)是代碼管理,用于批量處理git操作;第二類(lèi)是項(xiàng)目構(gòu)建,實(shí)現(xiàn)了動(dòng)態(tài)配置子模塊依賴(lài)、子模塊發(fā)布等功能。

5.1 代碼管理

vsub.sh腳本中封裝了常用的git命令,用于批量處理子倉(cāng)的git操作,實(shí)現(xiàn)邏輯相對(duì)簡(jiǎn)單,利用shell腳本將git命令封裝起來(lái)。

圖片

比如 ./vsub.sh -pull的實(shí)現(xiàn)邏輯,首先是cd進(jìn)入submodules目錄(submodules目錄存放了所有子倉(cāng)代碼),然后遍歷進(jìn)入子倉(cāng)目錄執(zhí)行g(shù)it pull --rebase命令,從而實(shí)現(xiàn)一個(gè)命令完成對(duì)所有子倉(cāng)的相同git操作,實(shí)現(xiàn)邏輯如下:

<!-- ./vsub.sh -pull代碼邏輯 -->
cd submodules
path=$currPath
files=$(ls $path)
for fileName in $files
do
if [ ! -d $fileName ]
then
continue
fi
cd $fileName
echo -e "\033[33mEntering $fileName\033[0m"
git pull --rebase
cd ..
done

5.2 項(xiàng)目構(gòu)建

(1)Sync 功能

通過(guò)執(zhí)行./vsub.sh sync命令將所有子模塊的代碼拉取到主工程的submodules目錄中。

Sync命令有3個(gè)功能:

1)如果子倉(cāng)代碼未拉取,則拉取代碼,并切換到repositories.xml中配置的devbranch;

2)如果子倉(cāng)代碼已拉取,則切換到repositories.xml中配置的devbranch;

3)考慮到在一些場(chǎng)景(比如jenkins構(gòu)建),使用分支檢出代碼可能會(huì)存在異常,在sync命令后面加 -c 參數(shù),則會(huì)使用repositories.xml中配置的commitid檢出指定分支代碼。

Sync流程如下:


圖片



(2)子模塊依賴(lài)處理

在之前我們依賴(lài)不同子倉(cāng)的代碼時(shí),需要手動(dòng)修改settings.gradle導(dǎo)入子模塊,然后修改build.gradle中的dependencies,如下圖。

<!-- settings.gradle -->
include ':app',':module_name_1',':module_name_2',':module_name_3'...

project(':module_name_1').projectDir = new File('E:/AndroidCode/module_name_1/code/')
project(':module_name_2').projectDir = new File('E:/AndroidCode/module_name_2/code/')
project(':module_name_3').projectDir = new File('E:/AndroidCode/module_name_3/code/')
...
<!-- build.gradle -->
dependencies {
api fileTree(dir: 'libs', include: ['*.jar'])
// 業(yè)務(wù)子模塊 begin
api project (':module_name_1')
api project (':module_name_2')
api project (':module_name_3')
// 業(yè)務(wù)子模塊 end
}
...

團(tuán)隊(duì)中每個(gè)人代碼的存放位置不同,在新版本拉完代碼后都需要手動(dòng)配置一番,比較繁瑣。

基于sync功能已經(jīng)把所有的子倉(cāng)代碼都拉到了submodules目錄中,現(xiàn)在我們項(xiàng)目在構(gòu)建時(shí)只需簡(jiǎn)單配置local.properties即可(local.properties配置如下圖),確定哪些子模塊是代碼依賴(lài),哪些子模塊是maven依賴(lài)。

<!-- 其中key module_name_x表示子模塊名,value 0表示maven依賴(lài),1表示代碼依賴(lài),默認(rèn)是maven依賴(lài),也就是,如果不配置某些子模塊則默認(rèn)maven依賴(lài) -->
module_name_1=0
module_name_2=0
module_name_3=1
module_name_4=1
module_name_5=1
module_name_6=1

子模塊依賴(lài)處理的流程如下:


圖片


(3)publish功能

通過(guò)執(zhí)行./vsub.sh publish命令實(shí)現(xiàn)一鍵編譯所有子模塊aar并上傳maven。

publish命令主要有4個(gè)功能:

1)如果子倉(cāng)代碼未拉取,則自動(dòng)拉取子倉(cāng)代碼;

2)如果是發(fā)布snapshot版本,則切換到devbranch分支最新代碼,version中包含snapshot字符串的子模塊,編譯生成aar并上傳maven;否則,則直接跳過(guò),不會(huì)編譯;

3)如果是發(fā)布release版本(即指定-a參數(shù)),則切換到commitid對(duì)應(yīng)的代碼,編譯生成release版本的aar,并上傳maven;

4)子倉(cāng)的編譯上傳順序根據(jù)配置的priority優(yōu)先級(jí)來(lái)執(zhí)行。

注:上述的devbranch、version、commitid、priority等都是repositories.xml中的配置項(xiàng)。

publish發(fā)布子模塊的流程如下:


圖片


六、ModularDevTool接入

接入本方案的前提是項(xiàng)目采用多代碼倉(cāng)的方式進(jìn)行模塊化開(kāi)發(fā)。具體接入步驟也比較簡(jiǎn)單。

第一步,主倉(cāng)依賴(lài)gradle插件modular_dev_plugin;

(該插件包含settings、tools、base、publish四個(gè)子插件,其中settings、tools和base插件配合實(shí)現(xiàn)子倉(cāng)代碼管理、動(dòng)態(tài)依賴(lài)處理,publish插件實(shí)現(xiàn)子倉(cāng)的aar發(fā)布)

第二步,主倉(cāng)的settings.gradle應(yīng)用settings插件,主倉(cāng)的app build.gradle中應(yīng)用tools和base插件;

第三步,主倉(cāng)根目錄添加repositories.xml配置文件和vsub腳本;

第四步,子倉(cāng)依賴(lài)modular_dev_plugin,并應(yīng)用publish插件;

第五步,中間層的子倉(cāng)(比如App→Shop→Lib,那Shop就是中間層子倉(cāng))對(duì)下一層子倉(cāng)的依賴(lài)版本號(hào)改成占位符,項(xiàng)目構(gòu)建時(shí)會(huì)自動(dòng)替換成repositories.xml中的版本號(hào)。如下圖:

dependencies {
// 對(duì)lib倉(cāng)的依賴(lài),原來(lái)是依賴(lài)具體的版本號(hào),現(xiàn)在改成“unified”占位符,項(xiàng)目構(gòu)建時(shí)會(huì)自動(dòng)替換成repositories.xml中的版本號(hào)
api "com.vivo.space.lib:vivospace_lib:unified"
}

至此,ModularDevTool就接入完成了。

七、現(xiàn)在的開(kāi)發(fā)流程

基于這個(gè)工具,現(xiàn)在我們官網(wǎng)的開(kāi)發(fā)流程如下:

第一步是clone主App倉(cāng)代碼,checkout對(duì)應(yīng)開(kāi)發(fā)分支,并在AndroidStudio打開(kāi)工程;

第二步是修改repositories.xml配置,需要進(jìn)行開(kāi)發(fā)的子倉(cāng),修改devbranch為對(duì)應(yīng)開(kāi)發(fā)分支,修改version為對(duì)應(yīng)版本號(hào);

圖片


第三步,通過(guò)./vsub.sh sync命令,檢出所有子模塊代碼;

第四步,修改local.properties中子倉(cāng)依賴(lài)的模式(maven依賴(lài)or代碼依賴(lài)),修改完成后點(diǎn)擊Sync一下,然后就可以正常進(jìn)行代碼開(kāi)發(fā)了,開(kāi)發(fā)體驗(yàn)與單工程多module模式完全一樣。

八、總結(jié)

這個(gè)工具已經(jīng)很成熟,在vivo錢(qián)包、vivo官網(wǎng)等項(xiàng)目已經(jīng)使用多年,通過(guò)該工具,開(kāi)發(fā)階段,實(shí)現(xiàn)多業(yè)務(wù)模塊集成式開(kāi)發(fā),解決代碼倉(cāng)分散管理和手動(dòng)配置依賴(lài)等繁瑣操作,發(fā)布階段,實(shí)現(xiàn)多種編譯模式以及一鍵編包能力,對(duì)于團(tuán)隊(duì)的開(kāi)發(fā)效率有很大提升,支撐官網(wǎng)app項(xiàng)目3+業(yè)務(wù)線(xiàn)并行迭代,并且代碼沖突降低50%以上。

責(zé)任編輯:龐桂玉 來(lái)源: vivo互聯(lián)網(wǎng)技術(shù)
相關(guān)推薦

2022-07-14 10:02:00

vivoUI適配開(kāi)發(fā)人員

2013-03-11 10:10:03

2013-03-11 10:00:13

前端模塊化

2013-08-20 16:33:52

前端模塊化

2014-04-22 10:19:40

objection模塊化開(kāi)發(fā)iOS

2010-08-02 09:21:48

Flex模塊化

2025-05-22 09:18:14

2017-05-12 14:00:07

大數(shù)據(jù)前端模塊化開(kāi)發(fā)

2023-11-08 13:55:27

2019-08-28 16:18:39

JavaScriptJS前端

2022-03-18 08:46:08

vivo官網(wǎng)APP首頁(yè)改版

2023-10-17 09:19:34

開(kāi)發(fā)Java

2020-11-09 10:46:35

CommonJS

2010-10-29 10:45:02

GrailsGroovy

2017-07-11 11:02:03

APP模塊化架構(gòu)

2013-08-20 16:45:22

重構(gòu)Web App模塊化

2010-08-02 09:10:36

Flex模塊化

2011-01-11 13:40:44

webcssdiv

2021-04-20 20:03:28

Systemjs模塊化前端

2025-06-06 01:00:00

Spring場(chǎng)景范式
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)