超理論壇客戶端源碼食用指南

分類:技術 時間:2016-10-25

關于項目

超理論壇 制作的Android客戶端,是我的個人項目-w-,目前剛剛完成向MVVM架構 Data Binding 的遷移,項目開源在 這里 。這是一篇與它配套的源碼食用指南,希望可以與有興趣的同學一起探討-w-

架構

使用了Data Binding的MVVM架構

包組織方式

項目中有8個包,分別是view, viewmodel, model, data, binding, network, meta, utils

  • view

即MVVM中的View層,在MVVM中,View層應該負責和UI相關,和業務邏輯無關的操作,要注意的是和UI相關并不僅僅指改變某個控件的顏色這種簡單的操作——實際上這些操作也基本被Data Binding接管了——切換到其它Activity、彈出Toast或者Dialog,也應該交給View來做,只是切換到哪個Activity,彈出的Toast內容是什么,就要讓Viewmodel來指定。關于View和ViewModel的具體分工,我也疑惑了很久,直到找到 這篇文章 ,我是先看到了它的中文版,疑惑于其中的ViewModel不應該持有任何Context的引用的說法,然后在谷歌上搜索,找到了它的首發地址,期待著會看到一些和中文版不同的更新,果然我在評論區里發現了作者對View和ViewModel職責的劃分,這個app也基本是按照它區分View和ViewModel。

  • viewmodel

即MVVM中的ViewModel層,處理和業務邏輯有關的功能,值得注意的是,在這個項目中,ViewModel既沒有持有任何Context,也沒有以任何形式持有View對象的引用,而是比較純粹的數據驅動。

  • model

即MVVM中的Model層,主要是一些POJO對象,用于JSON解析,或用于綁定在xml中。對一些情況來說,完全按照網頁接口返回的JSON解析出的對象并不適合直接綁定于xml并顯示在界面中,可能需要根據app當前的情況添加其它的數據,或對已有的數據進一步處理,因此在model包中一部分類是以Business開頭的,表示這些類是由其他model進一步處理得到的,用于與界面中的元素綁定。

  • data

一些有效范圍在整個Application的數據,存放在了這個類中,比如自己的賬戶信息。

  • binding

包含用于Data Binding框架的類,主要是各種BindingAdapter,其中有一個為了給RecyclerView綁定數據而實現的BindingAdapter,GitHub上有不少類似的第三方庫,比如 binding-collection-adapter ,但是不支持Support包中的DiffUtil,因此我自己重新造了一個輪子,代碼在binding包下的RecyclerViewBA.java中,支持對不同的數據渲染不同的layout,對實現了DiffItem接口的類,在list更新時會應用DiffUtil實現插入、刪除、移動的動畫效果,有興趣的同學可以參考一下,提一些建議:)。

  • network

和網絡有關的類,如對Retrofit、OkHttp的封裝、Retrofit的service等,Android 5.0以下的系統默認不支持TLS協議,導致網絡訪問失敗,修補的代碼也在這個包里。

  • meta

一些零零散散的內容,比如各種custom view,解析LaTeX和表情的代碼。

  • utils

各種工具類,主要是各種網絡請求,比如發帖、回帖、登錄、注銷這些。

對MVVM架構的理解

在所有MV*架構中,View都是一個只負責UI的角色,雖然有一些文章提議MVVM中的Model層應該包含業務邏輯,但我的這個項目仍然將model作為存放數據的“啞類”。一篇介紹MVVM架構的文章,大部分篇幅應該都用于闡述View和ViewModel的關系,對它們之間的關系,網上也有各種不同的說法,總結出來,有這么幾種:

  1. 讓ViewModel直接持有View的引用,需要時調用View暴露的各種方法

  2. 讓ViewModel持有View的Context的引用,來處理startActivity之類的需要Context的方法。

  3. View實現特定的接口,將View作為接口的對象傳遞給ViewModel

  4. 使用事件總線來在ViewModel和View之間傳遞消息。

第一種方法不符合MVVM中ViewModel應該對View一無所知的要求,也不符合松耦合的原則。第二種方法實用性不高——不是所有需要View層完成的事情都能用Context解決,比如更改menu。第三種方法不能適應復雜的需求——如果總共有三個需要暴露給ViewModel的方法,每個View可能只實現其中的某幾個,那可能最多要實現七個不同的接口,或者在ViewModel里持有多個簡單接口對象的引用——其實它們都指向同一個View。第四種方法是不錯的,不過事件總線用起來有些麻煩。

我自己在項目中使用的辦法是一種類似于事件總線的辦法,利用Data Binding中的Observable...類,在View中使用它們的addOnPropertyChangedCallback方法為這些ViewModel中的變量添加監聽器,在這些變量改變時,就可以執行監聽器中的回調函數。這樣,就把ViewModel和View解耦了,和事件總線一樣都是使用了觀察者模式。這樣,ViewModel可以實現比較純粹的數據驅動,對View保持一無所知,并且利于之后的維護。


Tags: MVVM模式 安卓開發

文章來源:http://www.jianshu.com/p/54ea9ada6fe3


ads
ads

相關文章
ads

相關文章

ad