Android組件化開發(fā)實踐

更新:Android組件化之通信(多模塊靖避,多進程)

Android項目中代碼量達(dá)到一定程度,編譯將是一件非常痛苦的事情,短則一兩分鐘,長則達(dá)到五六分鐘瞒瘸。Android studio推出instant run由于各種缺陷一般情況下是被關(guān)閉的……
組件化開發(fā)可以有效降低代碼模塊的耦合度,使代碼架構(gòu)更加清晰熄浓,同時模塊化的編譯可以有效減少編譯時間情臭,當(dāng)然總的編譯時間是不會減少的,只是App模塊化之后開發(fā)某個模塊時赌蔑,只需要編譯特定模塊俯在,可以快速編譯調(diào)試。

原理

組件化和插件化有些同學(xué)有些迷惑娃惯,簡單來說組件化是在編譯期分模塊跷乐,插件化是在運行期。一般插件化用于動態(tài)修復(fù)bug或者動態(tài)更新模塊趾浅,相對來說黑科技更多一些劈猿。

正常一個App中可以有多個module,但是一般只會有一個module是設(shè)置為application的潮孽,其他均設(shè)置為library揪荣,組件化開發(fā)就是要每個module都可以運行起來,因此在開發(fā)期間每個module均設(shè)置為application往史,發(fā)布時再進行合并仗颈。

實踐

本文主要介紹一下項目組件化開發(fā)過程碰到的問題和解決辦法,這里以
ModularizationApp項目為例椎例。ModularizationApp是一個組件化的app:

Paste_Image.png
Paste_Image.png
Paste_Image.png
Paste_Image.png
Paste_Image.png
  • 架構(gòu)

Paste_Image.png

其中App是主application挨决,ModuleA和ModuleB是兩個業(yè)務(wù)模塊,Library是基礎(chǔ)模塊订歪,包含所有模塊需要的依賴庫脖祈,以及一些工具類:如網(wǎng)絡(luò)訪問、時間工具等刷晋。代碼結(jié)構(gòu)如圖:

Paste_Image.png
  • Module作為application開發(fā)

ModuleA和ModuleB是相對獨立的業(yè)務(wù)模塊盖高,可以分別進行開發(fā),編譯時只編譯自身眼虱,具體實現(xiàn)時在gradle.properties中設(shè)置變量喻奥,如:IsBuildMudle=false
在模塊的的build.gradle中:

if (IsBuildMudle.toBoolean()) {
    apply plugin: 'com.android.application'
} else {
    apply plugin: 'com.android.library'
}

在主模塊的build.gradle中設(shè)置:

    if (!IsBuildMudle.toBoolean()) {
        compile project(':ModuleA')
        compile project(':ModuleB')
    } else {
        compile project(':Library')
    }

這樣每個module就可以獨立安裝使用了,注意在修改IsBuildMudle的值時捏悬,一定要sync gradle撞蚕。
當(dāng)module單獨運行和作為module運行時,其activity在manifest中設(shè)置也會不同过牙,這里可以根據(jù)IsBuildMudle設(shè)置不同的manifest:

    sourceSets {
        main {
            if (IsBuildMudle.toBoolean()) {
                manifest.srcFile 'src/main/debug/AndroidManifest.xml'
            } else {
                manifest.srcFile 'src/main/release/AndroidManifest.xml'
            }
        }
    }

分別在不同的目錄下創(chuàng)建manifest文件甥厦。一定要注意兩個manifest的同步問題纺铭,否則出現(xiàn)了莫名其名的bug,還找不到原因……

  • 資源沖突問題

當(dāng)分別開發(fā)模塊時刀疙,容易出資源重復(fù)命名的問題舶赔,可以在build.gradle中設(shè)置

resourcePrefix "module1_"

通過給模塊設(shè)置不同的資源前綴,可以避免重復(fù)命名庙洼。

  • Activity跳轉(zhuǎn)問題

拆分業(yè)務(wù)代碼時顿痪,自然會涉及到跨module的Activity跳轉(zhuǎn),當(dāng)單獨編譯時油够,自然是不能獲取到其他模塊的引用的蚁袭。有幾種方式可以實現(xiàn)跨模塊的喚起Activity:

隱式啟動
通過設(shè)置intent-filter實現(xiàn),這需要在manifest中插入大量代碼石咬,同時也降低了安全性(其他app就可以通過這種方式隨意啟動)揩悄。
通過類名跳轉(zhuǎn)
Android業(yè)務(wù)組件化開發(fā)實踐提出了一種通過類名跳轉(zhuǎn)的方式,使用腳本生成Rlist類鬼悠,比較方便快捷删性,但感覺不方便activity間傳遞數(shù)據(jù)。
Scheme跳轉(zhuǎn)
Scheme的方式是建立映射表焕窝,集中處理Activity蹬挺,這種方式可以傳遞一定的數(shù)據(jù)。Activity傳遞大量數(shù)據(jù)時可以通過EventBus來進行傳遞(其實即使通過intent顯示啟動它掂,也不要把大量數(shù)據(jù)放置在intent中巴帮,intent對數(shù)據(jù)大小有限制)。
在進行本次實踐時找到github上的一個url Router虐秋,同時支持http和程序內(nèi)Activity跳轉(zhuǎn)榕茧,而且通過注解的方式進行,使用非常方便客给,于是引入到了項目中用押。項目地址ActivityRouterActivityRouter的readme中已經(jīng)有比較詳細(xì)的wiki靶剑,但是還有一些需要注意的:

依賴問題:

ActivityRouter使用了apt方式蜻拨,因此每個使用的module中均需要設(shè)置

apt 'com.github.mzule.activityrouter:compiler:1.1.5'

注意是每個module,在Library module中設(shè)置

classpath 'com.neenbedankt.gradle.plugins:android-apt:1.8'

即可。

多module問題

ActivityRouter通過注解在編譯時生成mapping抬虽,如果多個module設(shè)置依賴官觅,就會生成多個java文件,導(dǎo)致源文件重復(fù)阐污,編譯出錯,ActivityRouter目前提供了解決方法咱圆,但是還沒有正式發(fā)布版本笛辟,可以設(shè)置:

compile 'com.github.mzule.activityrouter:activityrouter:1.1.9' 
apt 'com.github.mzule.activityrouter:compiler:1.1.6'

使用功氨。使用在application中注解:

@Modules({"app", "moduleA", "moduleB"})
public class ModularizationApplication extends Application {
}

每個module中創(chuàng)建空java類注解:

@Module("moduleA")
public class ModuleA {
}

具體可以clone ModularizationApp查看代碼。

編譯運行

當(dāng)在gradle.properties中設(shè)置IsBuildMudle=true時手幢,可以獨立運行每個module捷凄,獨立運行調(diào)試,當(dāng)設(shè)置IsBuildMudle=false围来,可以編譯運行整個project跺涤,注意IsBuildMudle變量設(shè)置改變時,要對gradle進行sync监透。

運行過程中有什么問題可以評論或者在github中提issue桶错。

參考:
http://kymjs.com/code/2016/10/18/01
https://github.com/mzule/ActivityRouter
https://github.com/liangzhitao/ComponentizationApp

Other

歡迎關(guān)注公眾號wutongke,每天推送移動開發(fā)前沿技術(shù)文章:

wutongke

推薦閱讀:

Android 組件化開發(fā)原理和配置

Android組件化開發(fā)實踐

Android組件化之通信(多模塊胀蛮,多進程)

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末院刁,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子粪狼,更是在濱河造成了極大的恐慌退腥,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,651評論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件再榄,死亡現(xiàn)場離奇詭異狡刘,居然都是意外死亡,警方通過查閱死者的電腦和手機困鸥,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,468評論 3 392
  • 文/潘曉璐 我一進店門嗅蔬,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人窝革,你說我怎么就攤上這事购城。” “怎么了虐译?”我有些...
    開封第一講書人閱讀 162,931評論 0 353
  • 文/不壞的土叔 我叫張陵瘪板,是天一觀的道長。 經(jīng)常有香客問我漆诽,道長侮攀,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,218評論 1 292
  • 正文 為了忘掉前任厢拭,我火速辦了婚禮兰英,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘供鸠。我一直安慰自己畦贸,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 67,234評論 6 388
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著薄坏,像睡著了一般趋厉。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上胶坠,一...
    開封第一講書人閱讀 51,198評論 1 299
  • 那天君账,我揣著相機與錄音,去河邊找鬼沈善。 笑死乡数,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的闻牡。 我是一名探鬼主播净赴,決...
    沈念sama閱讀 40,084評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼澈侠!你這毒婦竟也來了劫侧?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 38,926評論 0 274
  • 序言:老撾萬榮一對情侶失蹤哨啃,失蹤者是張志新(化名)和其女友劉穎烧栋,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體拳球,經(jīng)...
    沈念sama閱讀 45,341評論 1 311
  • 正文 獨居荒郊野嶺守林人離奇死亡审姓,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,563評論 2 333
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了祝峻。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片魔吐。...
    茶點故事閱讀 39,731評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖莱找,靈堂內(nèi)的尸體忽然破棺而出酬姆,到底是詐尸還是另有隱情,我是刑警寧澤奥溺,帶...
    沈念sama閱讀 35,430評論 5 343
  • 正文 年R本政府宣布辞色,位于F島的核電站,受9級特大地震影響浮定,放射性物質(zhì)發(fā)生泄漏相满。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,036評論 3 326
  • 文/蒙蒙 一桦卒、第九天 我趴在偏房一處隱蔽的房頂上張望立美。 院中可真熱鬧,春花似錦方灾、人聲如沸建蹄。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,676評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽躲撰。三九已至针贬,卻和暖如春击费,著一層夾襖步出監(jiān)牢的瞬間拢蛋,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,829評論 1 269
  • 我被黑心中介騙來泰國打工蔫巩, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留谆棱,地道東北人。 一個月前我還...
    沈念sama閱讀 47,743評論 2 368
  • 正文 我出身青樓圆仔,卻偏偏與公主長得像垃瞧,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子坪郭,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,629評論 2 354

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