Android mvvm arch的一次架構(gòu)實現(xiàn)

項目地址:mvvmClient

兄dai,2019的寒冷不知道你感受到了沒,反正我已經(jīng)兩個月沒有發(fā)工資了,作為一個開發(fā)沒有了工資就等于沒有了靈魂,但一切為了運行的更加絲滑,哥們把一篇mvvmClient奉上。

先放圖


屏幕快照 2019-01-06 上午11.00.01.png
屏幕快照 2019-01-06 上午11.01.05.png
屏幕快照 2019-01-06 上午11.02.05.png

....

就這些了,畢竟這次界面不是重點,接下來進入主題

  1. 項目架構(gòu)
    模塊之間解耦使用arouter,每個模塊可以自己單獨運行起來。代碼解藕使用dagger2。
    使用mvvm架構(gòu),整體嚴(yán)格按照Architecture Component規(guī)范,統(tǒng)一數(shù)據(jù)源

2.用到的第三方庫


屏幕快照 2019-01-06 上午11.08.36.png

3.項目目錄結(jié)構(gòu)

app // 殼app
library_core // 核心庫 提供基礎(chǔ)的網(wǎng)絡(luò)操作
library_common // 公共庫
module_account // 登錄模塊
module_player // 玩Android api 簡單實現(xiàn)

屏幕快照 2019-01-06 上午11.13.20.png
屏幕快照 2019-01-06 上午11.14.32.png

4.數(shù)據(jù)流轉(zhuǎn)具體邏輯
repository層
根據(jù)本次請求的請求策略來決定從網(wǎng)絡(luò)還是從數(shù)據(jù)庫(緩存,使用room)獲取數(shù)據(jù),提供給viewmodel 層的是livedata viewmodel層 從repository中拿到數(shù)據(jù)后處理方式有很多種。
a. 直接把數(shù)據(jù)提供給UI層,UI層來渲染對應(yīng)的view(databinding)
b. 處理和加工數(shù)據(jù),把livedata數(shù)據(jù)轉(zhuǎn)化為 MediatorLiveData,通過MediatorLiveData把數(shù)據(jù)拆分為多個更加具體的livedata傳遞給UI(推薦用法)
UI層 負(fù)責(zé)展示和渲染(databinding)

5.解決的問題
使用dagger2模塊化開發(fā)的一次嘗試,dagger2解藕后的多個模塊單獨運行的一個思路 遵守Android arch 規(guī)范的實現(xiàn) 適合敏捷開發(fā)和項目規(guī)模比較大的開發(fā)模式

6.整體流程

如果關(guān)注點是使用該框架,那么其實整體用法還是固定的,先說說用法吧

a. 新建功能模塊module,名字假如為moduleTest目錄結(jié)構(gòu)按照 moduleplayer的就可以,當(dāng)然需要你在project 目錄下,創(chuàng)建debug 目錄,這是為了使你的moduleTest
能夠自己起飛,單獨作為一個項目來運行, 在debug目錄下新建你的application,繼承baseapplication實現(xiàn)initDi(); 把相關(guān)的依賴配置好,然后component(這里假如你會使用dagger2)

b. 到項目真正功能的開發(fā)了,那就說說分包
api -- retorfit的數(shù)據(jù)接口
db -- 數(shù)據(jù)庫相關(guān)(如果你要自己維護緩存,那這個地方需要你自己來寫,用的room,如果緩存策略能滿足你的開發(fā),那這個地方可以忽略,當(dāng)然后期會加入etag cache-control等默認(rèn)服務(wù)端緩存策略)
di -- 注入 api下的數(shù)據(jù)接口,ui相關(guān)的activity fragment viewmodel 都是在這個地方注入的,至于是怎么注入的這個問題后面講
repository -- 倉庫,我們不提供數(shù)據(jù),我們只是數(shù)據(jù)的搬運工。數(shù)據(jù)的獲取是在這里,因此所有請求的響應(yīng)你都能在這里看到她的身影
ui -- 這個不說了,我知道你肯定是Android開發(fā) emmm... 還是說下吧 activity fragment 中的職責(zé)就是控制view層,響應(yīng)用戶操作,所以不要把處理業(yè)務(wù)的邏輯放在這里,
可以放到viewmodel中來處理,然后再通過具體的livedata驅(qū)動UI層的view作出響應(yīng),所以他們應(yīng)該是簡介的,只監(jiān)聽livedata的變化,把這變化傳遞給view,xml使用databinding,(我這里沒有使用太多,原則
上講可以多用一些bindingadapter,但是我總覺得有點本末倒置了,數(shù)據(jù)驅(qū)動就要在xml中處理過多的邏輯,這讓我想到了java的jsp,和php,我們是為了維護訪方便,解藕清晰才框架的,不是嗎?這個就自己考慮吧,沒有定義binding包是因為我到現(xiàn)在也沒說服自己)
viewmodel -- 這一層和mvp的p層有點像,但是更加絲滑(個人感覺),數(shù)據(jù)處理不再考慮生命周期的限制,從repository拿到數(shù)據(jù)可以加工也可直接使用(建議加工后成為具體有意義的數(shù)據(jù)再給UI層,應(yīng)為不加工的后果可能是把你的架構(gòu)變成了mvc,哈哈哈,我就是從這走過來的)
vo -- 這個就是請求的實體類,當(dāng)然如果自己維護緩存,也可以當(dāng)作room的entity層,使用提供的緩存的話,就把你要緩存的實體實現(xiàn)Serializable
widget -- 控件

c. 框架的構(gòu)建流程

1.依賴關(guān)系
從builde.gradle(app)中能看的出來 整體的依賴規(guī)則

if (!IsBuildMudle.toBoolean()) {
implementation project(':moduleAccount')
implementation project(':moduleGank')
implementation project(':moduleplayer')
} else {
implementation project(':library_core')
}

每個模塊的都依賴 api project(':library_core')

library_core依賴library_common

  1. library_core 的職責(zé)

library_core 提供基礎(chǔ)的網(wǎng)絡(luò)請求模塊,基礎(chǔ)的注入模塊,一些工具類(后期放到common中),可以看到?jīng)]有components ,這是因為踩坑dagger2的時候(有時間再探探這個坑,或者有dagger2大神給解決下,總覺得目前的不完美)沒能使用dependencies和subcomponent這些姿勢來解決多個components之間的依賴
,所以用了不是很完美的一個components 多個module的實現(xiàn)方式,還算絲滑,使用dagger-android來做的四大組件的注入,在baseappliction中暴露initDi方法供繼承者注入自己的四大組件,當(dāng)然了需要實現(xiàn)baseactitivity 或者 basefragment,因為他們的注入是在activity的oncreate中注入了,這時候你可能會問,為什么不再baseactivity中統(tǒng)一注入呢,
畢竟baseactivity 的handactivity 會holader住所有activity的創(chuàng)建,這個問題我也想過,這姿勢肯定很爽,但是我沒能實現(xiàn),一直報錯讓我不得已用了現(xiàn)在這個姿勢,至于出錯的原因是什么呢?我想是跟上面說的 dagger2的dependencies和subcomponent有關(guān),這個留著以后探索。至于注入這方面的就不多講了
網(wǎng)絡(luò)請求使用的retorfit 加 LiveDataCallAdapterFactory,livedatacalladapter顯得有些脆弱,這里是用的網(wǎng)上找來的,后續(xù)會自己動手讓她strong一點,至于攔截器這些就不多說了。
好了關(guān)鍵的網(wǎng)絡(luò)請求和注入大致就是上面這些了

  1. library_common 的職責(zé)
    這個就隨意些了,common都很熟悉,目前只是把arouter的跳轉(zhuǎn)path的定義和一些工具類放在這里了。存在的意義是我覺從一開始覺得library_core在開發(fā)的時候不要頻繁的動,common來處理一些公共資源

  2. 看完上面這些如果還是迷茫的,那不是你的錯,我的。。好吧,自己擼一遍登錄注冊就明白了(嘿嘿嘿)

  3. 未完待續(xù)..

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容