動態(tài)注冊接口
Provider.register(AbcInterface.class,new AbcInterfaceImpl())
獲取實(shí)例并調(diào)用
Provider.get(AbcInterface.class).doSomething()
(5) EventBus
這個自不必說,雖然說濫用是一個問題,但是有些場景下,使用事件還是最為方便簡單的方式
(6) 組件 API 模塊
上面提到的接口和事件以及一些跨組件使用的 Model 放到哪里好呢?如果直接將這些類下沉到一個公共組件中,由于業(yè)務(wù)的頻繁更新,這個公共組件可能會更新得十分頻繁,開發(fā)也十分的不方便,所以使用公共組件是行不通的,于是我們采取了另一種方式——組件 API :為每個有對外暴露需求的組件添加一個 API 模塊,API 模塊中只包含對外暴露的 Model 和組件通信用的 Interface 與 Event。有需要引用這些類的組件只要依賴 API 即可。
[圖片上傳中…(image-a39cd0-1598345691997-6)]
一個典型的組件工程結(jié)構(gòu)是這個樣子:
以上圖為例,它包含三個模塊:
template :組件代碼,它包含了這個組件所有業(yè)務(wù)代碼
template-api:組件的接口模塊,專門用于與其他組件通信,只包含 Model、Interface 和 Event,不存在任何業(yè)務(wù)和邏輯代碼
app 模塊:用于獨(dú)立運(yùn)行 app,它直接依賴組件模塊,只要添加一些簡單的配置,即可實(shí)現(xiàn)組件獨(dú)立運(yùn)行。
組件半自動拆分
有了解耦的方法,剩下的就是采取行動拆分組件了,拆組件是一個很頭疼的問題,它非常考慮一個人的細(xì)心與耐心,由于無法準(zhǔn)確知道有哪些代碼要被拆走,也不能直觀的知曉依賴關(guān)系,移動變得非常的困難且容易出錯,一旦不能一次性拆分成功,到處都是編譯錯誤,便只能靠人肉一點(diǎn)一點(diǎn)的挪。
工欲善其事,必先利其器。為了解決這個問題,我們開發(fā)了一個輔助工具 RefactorMan: 它可以遞歸的解析出工程中所有源碼的引用和被引用情況,同時會根據(jù)預(yù)設(shè)規(guī)則自動分析出所有不合理的依賴,在開發(fā)人員根據(jù)提示解決了不合理依賴之后,即可將組件一鍵移出,大大減少了拆組件的工作量。我們在組件化初期曾經(jīng)走過一些彎路,最初拆出的八個組件工程的的部分源碼經(jīng)歷了幾次的反復(fù)移動才得出最優(yōu)解,而有了 RefactorMan,我們可以面對反復(fù)的拆分和組合組件有恃無恐。
Bonus :由于可以分析和移動資源,所以額外獲得了清理無用資源的功能。
聯(lián)合編譯完整包
單獨(dú)運(yùn)行組件 app 并不能完整的覆蓋所有的 case,尤其是在給 QA 測試的時候,還是需要編譯完整的主工程包的,所以我們需要一個直接編譯完整包的方案:
最初我們的實(shí)現(xiàn)方式只針對組件,比較簡單:
首先在 setting.gradle 中動態(tài)引入組件 module:
def allComponents = [“base”, “account” … “template” …]
allComponents.forEach({ name ->
if (shouldUseSource(name)) {
// 動態(tài)引入外部模塊
include “:
n
a
m
e
"
p
r
o
j
e
c
t
(
"
:
{name}" project(":
name"project(":{name}”).projectDir = getComponentDir(name);
}
})
然后在 app/build.gradle 中切換依賴,需要將所有被間接依賴的組件全部 exclude 以防止同時依賴了一個組件的 module 和 aar:
allComponents.forEach({ name ->
if (shouldUseSource(name)) {
implementation(project(“:KaTeX parse error: Expected 'EOF', got '}' at position 46: …PONENT_GROUP } }? else { impleme…{COMPONENT_GROUP}:
n
a
m
e
:
{name}:
name:{versions[name]}”) { exclude group: COMPONENT_GROUP }
}
})
由于所有組件的 group 都是一樣的,所以這樣做并沒有什么問題,但是后來一些基礎(chǔ) SDK 也出現(xiàn)了這種需求,這時候就需要一種通用的源碼依賴方案,因此做了一下修改,直接使用 gradle 提供的依賴替換功能,只需要修改 setting.gradle 即可:
// … 忽略讀取配置代碼 …
configs.forEach { artifact, prj ->
include “:
p
r
j
.
n
a
m
e
"
p
r
o
j
e
c
t
(
"
:
{prj.name}" project(":
prj.name"project(":{prj.name}”).projectDir = new File(prj.dir)
}
gradle.allprojects { project ->
if (project == project.rootProject) {
return
}
project.configurations.all {
resolutionStrategy.dependencySubstitution {
configs.forEach { artifact, prj ->
// 在這里進(jìn)行替換
substitute module(artifact) with project(“??{prj.name}”)
}
}
}
}
而 build.gradle 的依賴寫法與普通的工程完全一樣。
普通狀態(tài)下的的主工程:
源碼引用 template 組件后的主工程:
這樣我們就可以像之前在單工程中一樣寫代碼了。
得益于源碼引用,我們直接在提交組件代碼的時候,CI 會自動聯(lián)合主工程編譯出完整包,QA 會根據(jù)完整包進(jìn)行測試,在測試通過后即可自動發(fā)布到公司的倉庫,并通過內(nèi)部的集成平臺集成到主工程
小 tip :工程 .idea/vcs.xml 中定義了當(dāng)前工程關(guān)聯(lián)的 Git 倉庫,可以在聯(lián)合編譯的同時通過修改 vcs.xml 來把組件目錄也關(guān)聯(lián)到主工程 Git 配置中,在開發(fā)過程中就可以使用 Android Studio 的內(nèi)置 Git 功能了
包含子業(yè)務(wù)線的組件
我們當(dāng)前的組件,絕大部分是一個組件一個倉庫的,對于一般的組件來說,并沒有什么問題,但是對于有的業(yè)務(wù)線,本身規(guī)模比較大,包含了若干個子業(yè)務(wù),比如知乎大學(xué),電子書、live 和私家課等子業(yè)務(wù),這些子業(yè)務(wù)本身功能獨(dú)立,但是共享整個業(yè)務(wù)線的基礎(chǔ)代碼,同時大業(yè)務(wù)線也有會一些匯總所有子業(yè)務(wù)的頁面,它們的關(guān)系是這個樣子:
這幾個業(yè)務(wù)如果都要拆分出去獨(dú)立成組件,然后抽離公共部分成為也成為一個業(yè)務(wù)線基礎(chǔ)組件,這時候會面臨一個很大的問題:由于幾條業(yè)務(wù)線都屬于同一個主業(yè)務(wù)線,做活動或者上新 Feature 的時候,這幾個組件經(jīng)常會發(fā)生聯(lián)動,需要先更新 base 再更新其他業(yè)務(wù)線,提交 mr 也要同時提多個倉庫,出現(xiàn)頻繁的連鎖更新;而如果不拆的話,業(yè)務(wù)線代碼本身就已經(jīng)很龐大,即使是單獨(dú)編譯組件 app 也會很慢,并且隨著時間的推移,各個業(yè)務(wù)線的代碼邊界會像組件化之前的主工程一樣逐漸劣化,耦合會越來越嚴(yán)重。
所以現(xiàn)在需求變成了這個樣子:
- 對外保持只有一個組件:有聯(lián)動需求的時候,組件仍然只發(fā)布一次更新
自我介紹一下,小編13年上海交大畢業(yè),曾經(jīng)在小公司待過,也去過華為、OPPO等大廠,18年進(jìn)入阿里一直到現(xiàn)在。
深知大多數(shù)Android工程師,想要提升技能,往往是自己摸索成長或者是報班學(xué)習(xí),但對于培訓(xùn)機(jī)構(gòu)動則幾千的學(xué)費(fèi),著實(shí)壓力不小。自己不成體系的自學(xué)效果低效又漫長,而且極易碰到天花板技術(shù)停滯不前!
因此收集整理了一份《2024年Android移動開發(fā)全套學(xué)習(xí)資料》,初衷也很簡單,就是希望能夠幫助到想自學(xué)提升又不知道該從何學(xué)起的朋友,同時減輕大家的負(fù)擔(dān)。
既有適合小白學(xué)習(xí)的零基礎(chǔ)資料,也有適合3年以上經(jīng)驗(yàn)的小伙伴深入學(xué)習(xí)提升的進(jìn)階課程,基本涵蓋了95%以上Android開發(fā)知識點(diǎn),真正體系化!
由于文件比較大,這里只是將部分目錄大綱截圖出來,每個節(jié)點(diǎn)里面都包含大廠面經(jīng)、學(xué)習(xí)筆記、源碼講義、實(shí)戰(zhàn)項(xiàng)目、講解視頻,并且后續(xù)會持續(xù)更新
如果你覺得這些內(nèi)容對你有幫助,可以添加V獲?。簐ip204888 (備注Android)
寫在最后
很多人在剛接觸這個行業(yè)的時候或者是在遇到瓶頸期的時候,總會遇到一些問題,比如學(xué)了一段時間感覺沒有方向感,不知道該從哪里入手去學(xué)習(xí),對此我整理了一些資料
如果你熟練掌握以下列出的知識點(diǎn),相信將會大大增加你通過前兩輪技術(shù)面試的幾率!這些內(nèi)容都供大家參考,互相學(xué)習(xí)。
①「Android面試真題解析大全」PDF完整高清版+②「Android面試知識體系」學(xué)習(xí)思維導(dǎo)圖壓縮包,最后覺得有幫助、有需要的朋友可以點(diǎn)個贊
本文已被CODING開源項(xiàng)目:《Android學(xué)習(xí)筆記總結(jié)+移動架構(gòu)視頻+大廠面試真題+項(xiàng)目實(shí)戰(zhàn)源碼》收錄
一個人可以走的很快,但一群人才能走的更遠(yuǎn)。如果你從事以下工作或?qū)σ韵赂信d趣,歡迎戳這里加入程序員的圈子,讓我們一起學(xué)習(xí)成長!
AI人工智能、Android移動開發(fā)、AIGC大模型、C C#、Go語言、Java、Linux運(yùn)維、云計(jì)算、MySQL、PMP、網(wǎng)絡(luò)安全、Python爬蟲、UE5、UI設(shè)計(jì)、Unity3D、Web前端開發(fā)、產(chǎn)品經(jīng)理、車載開發(fā)、大數(shù)據(jù)、鴻蒙、計(jì)算機(jī)網(wǎng)絡(luò)、嵌入式物聯(lián)網(wǎng)、軟件測試、數(shù)據(jù)結(jié)構(gòu)與算法、音視頻開發(fā)、Flutter、IOS開發(fā)、PHP開發(fā)、.NET、安卓逆向、云計(jì)算文章來源:http://www.zghlxwxcb.cn/news/detail-854453.html
AIGC大模型、C C#、Go語言、Java、Linux運(yùn)維、云計(jì)算、MySQL、PMP、網(wǎng)絡(luò)安全、Python爬蟲、UE5、UI設(shè)計(jì)、Unity3D、Web前端開發(fā)、產(chǎn)品經(jīng)理、車載開發(fā)、大數(shù)據(jù)、鴻蒙、計(jì)算機(jī)網(wǎng)絡(luò)、嵌入式物聯(lián)網(wǎng)、軟件測試、數(shù)據(jù)結(jié)構(gòu)與算法、音視頻開發(fā)、Flutter、IOS開發(fā)、PHP開發(fā)、.NET、安卓逆向、云計(jì)算**文章來源地址http://www.zghlxwxcb.cn/news/detail-854453.html
到了這里,關(guān)于GitHub標(biāo)星9-8k,知乎閱讀10w+,這些年Android面試的那些套路的文章就介紹完了。如果您還想了解更多內(nèi)容,請?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!