分享一個我開發的MVVM架構的開源小項目

本文同步發表於我的微信公衆號,掃一掃文章底部的二維碼或在微信搜索 郭霖 即可關注,每個工作日都有文章更新。

大家好,今天跟大家分享一個我開發的MVVM架構的開源小項目。

話說這個小項目已經提前跟大家預熱很久了,也是被不少朋友催了很多次。我之前在公衆號裏透漏過這個項目能夠幫助大家更好地理解MVVM架構,當然我也希望確實如此。

雖說這篇文章重點是向大家介紹這個開源小項目的,但是我並不希望就寫得如此簡單,我準備把它寫成一篇乾貨文章。

一切先從Jetpack說起。我在去年年底的時候抽時間研究了下Google的Jetpack,這是一款在18年Google I/O大會上推出的Android開發組件工具集,旨在幫助我們輕鬆構建更穩定、更健壯、以及更可維護的應用程序。

Jetpack又引出了好幾個相關聯的概念,比如說Architecture Components,MVVM,它們之間是什麼關係呢?

這裏我先給大家做個普及,Architecture Components是Google在17年的I/O大會上推出的架構組件工具集,18年被併入到了Jetpack當中,所以嚴格上來講,Architecture Components目前是Jetpack的一部分。而MVVM(Model-View-ViewModel)是一種代碼架構模式,被廣泛應用在Android程序設計領域,類似的架構模式還有MVP、MVC等。但是,目前Google最爲推薦的代碼架構模式就是MVVM,甚至Jetpack中的許多組件就是爲了便於實現MVVM架構的項目而提供的。

也就是說,藉助Jetpack,我們就可以輕鬆地編寫一個MVVM架構的項目了,當然前提是你對Jetpack已經比較瞭解。

這裏我先給出一張Jetpack的全家福:

可以看到,Jetpack主要分爲4個部分,基礎、架構、行爲、界面。你會發現,裏面有很多東西都是我們平時經常使用的,像AppCompat、通知、權限,甚至連Fragment都屬於Jetpack。由此可見,Jetpack並不全是些新東西,只要是能夠幫助開發者更好更方便地構建應用程序的組件,Google都將其歸納入了Jetpack。

在Jetpack這麼多組件當中,其中最需要我們關注的就是架構組件了,這些是幫助我們編寫出MVVM架構程序的核心。像數據綁定、Lifecycles、LiveData、Room、ViewModel等,都可以說是構建一個MVVM架構程序的重要組成部分。當然,上述組件中你並不一定要全部使用,而是可以選着使用,視自己項目的實際情況選取那些最合適的組件即可。

本篇文章我並不會帶着大家一起學習Jetpack中的諸多組件,只是做個簡單科普而已。可能有不少朋友還從來沒接觸過Jetpack,這裏我貼出幾個我當時用來學習的鏈接,大家可以適當參考一下。

ViewModels : A Simple Example
https://medium.com/androiddevelopers/viewmodels-a-simple-example-ed5ac416317e

Basic Example of LiveData and ViewModel
https://medium.com/@taman.neupane/basic-example-of-livedata-and-viewmodel-14d5af922d0

Handling Lifecycles with Lifecycle-Aware Components
https://developer.android.com/topic/libraries/architecture/lifecycle

Android lifecycle-aware components codelab
https://codelabs.developers.google.com/codelabs/android-lifecycles

Build an App with Architecture Components
https://codelabs.developers.google.com/codelabs/build-app-with-arch-components/index.html

上述鏈接中包括了Google工程師的博客、Android的官方文檔、以及兩個Google Codelabs項目,當然我還參考了很多其他的資料。但是當我把這些資料都看完,並且將Codelabs項目也跟着教程一步步敲出來了之後,我始終還是覺得不能融會貫通,對Jetpack以及MVVM架構的把控程度都還不夠。我就意識到少了點什麼,看來我得自己從頭寫一個MVVM的項目才行,這樣才能做到對各個知識點和坑點無死角地掃描,這也是我決定做這樣一個小開源項目的初衷。

確定了要做的事情之後,接下來就是思考要做一個什麼樣的開源項目了,有以下幾個標準吧:

  1. 要用Jetpack組件來實現。
  2. 項目要越小越好,突出MVVM主題。
  3. 作爲開源項目,代碼要儘可能易懂,有學習價值。

其實這對我來說並不難想,列出了以上幾個標準之後,我一下子就想到了要做一個什麼開源項目——酷歐天氣Jetpack版。酷歐天氣作爲《第一行代碼》中的經典學習項目,已經被無數小夥伴練習過,大家都是非常熟悉的。而開源這樣一個項目的Jetpack版,主體功能都是保持和之前的酷歐天氣版本一致的,只是裏面的代碼實現全部替換成了Jetpack組件和MVVM架構,這樣更加可以突顯出我們要關注的主題,另外也可以方便對比MVVM架構和非MVVM架構項目之間的區別。

這裏我先給出一張酷歐天氣Jetpack版的架構設計圖,這張圖是模仿Google Codelabs的Sunshine項目畫出來的,上面也已經給出了這個項目的鏈接。擁有良好架構設計的項目都是可以用簡潔清晰的架構圖表示出來的,而一個雜亂無章沒有架構設計的項目則很難用架構圖表示出來。

上述架構圖可能一開始看你會找不着重點,其實這張架構圖非常清晰,我來帶大家解讀一下。

首先我們通過這張架構圖成功將程序分爲了若干層。

綠色部分表示的是UI控制層,這部分就是我們平時寫的Activity和Fragment。

藍色部分表示的是ViewModel層,ViewModel用於持有和UI元素相關的數據,以保證這些數據在屏幕旋轉時不會丟失,以及負責和倉庫之間進行通訊。

黃色部分表示的是倉庫層,倉庫層要做的工作是自主判斷接口請求的數據應該是從數據庫中讀取還是從網絡中獲取,並將數據返回給調用方。如果是從網絡中獲取的話還要將這些數據存入到數據庫當中,以避免下次重複從網絡中獲取。簡而言之,倉庫的工作就是在本地和網絡數據之間做一個分配和調度的工作,調用方不管你的數據是從何而來的,我只是要從你倉庫這裏獲取數據而已,而倉庫則要自主分配如何更好更快地將數據提供給調用方。

接下來灰色部分表示是的本地數據層,實現方式並不固定,我使用了LitePal來進行數據持久化處理,你也可以使用別的框架(這裏我沒有使用官方的Room還是因爲Room真的不太好用)。

最後紅色部分表示的是網絡數據層,這裏使用了Retrofit從web服務接口獲取數據。

藉助這張架構圖,我想會在很大程度上便於大家理解酷歐天氣Jetpack版這個開源項目,而如果你自己編寫的項目也能嘗試畫出這樣一張架構圖,那麼你的代碼結構一定是非常不錯的。

另外對於這張架構圖我還有必要再解釋一下,圖中所有的箭頭都是單向的,比方說WeatherActivity指向了WeatherViewModel,表示WeatherActivity持有WeatherViewModel的引用,但是反過來WeatherViewModel不能持有WeatherActivity的引用。其他的幾層也是一樣的道理,一個箭頭就表示持有一個引用。

還有,引用不能跨層持有,就比方說UI控制層不能持有倉庫層的引用,每一層的組件都只能和它的相鄰層交互。

大概就介紹這麼多吧,剩下的就靠大家自己去閱讀源碼進行學習了,酷歐天氣Jetpack版的開源地址是:

https://github.com/guolindev/coolweatherjetpack

項目運行截圖如下:
             
另外也請大家隨手幫我點個star,多一些鼓勵,我也就多一些持續貢獻開源的動力。

最後,希望這個項目能夠幫助大家更好地學習Jetpack,更好地學習MVVM架構。


關注我的技術公衆號,每個工作日都有優質技術文章推送。關注我的娛樂公衆號,工作、學習累了的時候放鬆一下自己。

微信掃一掃下方二維碼即可關注:

        

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章