android MVVM+ dagger2 +Arouter 走的那些坑

適應人羣:對相關技術有一點了解的人,這篇文章主要是記錄自己在使用中遇到的一些問題,網上記錄的文章要麼太過零散,要麼都是千遍一律的小白入手,希望能給代價帶來一點幫助

在記錄的同時,我慢慢的自己也在總結,之所以出現這些問題的根節在於對知識點理解的不成體系,有些問題本身已經在官網文檔中有記錄,另外自己使用的時候是現學現賣,網上很多資料過於小白,真正實踐的問題方面大部分單獨一篇一小段,每次踩坑後又要繼續查,所以希望做成一個大全

MVVM 與MVP 的區別易錯點

作爲一個超級小白剛看到mvvm的時候,很詫異,mvvm 不就是一個Model (數據模型) ,ViewModel(業務層) ,View(視圖層),另一個VM在哪?原來MVVM的VM是ViewModel 的縮寫,但是明明就是業務層爲什麼叫ViewModel呢?

引用其他文章看到的一句話

vewModel 通過雙向數據綁定把 View 層和 Model 層連接了起來,而View 和 Model 之間的同步工作完全是自動的,無需人爲干涉,因此開發者只需關注業務邏輯,不需要手動操作DOM, 不需要關注數據狀態的同步問題,複雜的數據狀態維護完全由 MVVM 來統一管理···

所以個人認爲最大的區別就是上面這段話,總結下來,MVP的優點MVVM也有,低耦合,可重用,可測試;MVVM有的雙向綁定,MVP卻沒有。

databinding

databinding 將數據模型通過表達綁定到UI組件上,讓代碼更簡潔,讓程序員更加專注於業務代碼的編寫,比如省去了findViewById ,設置值更新UI的代碼。。,事件綁定,規避了NullPointException等。
性能方面: 在編譯時生成相應的設置值,綁定view的代碼,再次使用該控件無需(FindViewById)遍歷查找,原理
官方推薦實踐:不要在佈局文件中編寫複雜邏輯的表達式
缺點: 不利於調試(還沒遇到過,只是簡單表達式),個人覺得xml中對語法提示支持還不是很好,例如與String.format結合後,屬性彈不出,錯誤提示不太友好
推薦的插件:databinding

明明在xml中綁定了事件和屬性但界面沒有變化
忘記給databinding中的變量設置值

databinding.setVabrible(BR.viewModel,viewModel);

NUll ,默認如果屬性字段爲空,程序不會報錯,但是界面會顯示個Null,規避方法 `` 在Esc 鍵下面

android:text="@{item.name ?? ``}"

與String.xml 格式化的結合使用
需要注意的是會有嚴格類型檢查 %d %f %s 等

<string name="fake_data">待處理%1d</string>
<string name="fake_data1">待處理%1s</string>
android:text="@{@fake_data(item.fake_count)}"
android:text="@{@fake_data(item.fake_str:``)}"

/ data binding error ****msg:Identifiers must have user defined types from the XML file. View is missing it
忘記導入view

<layout xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools">
    <data>
        <import type="android.view.View" />
    </data>
<import type="android.view.View" />

“找不到符號 BR”

Dagger2、DataBinding、ButterKnife、DbFlow等這些第三方庫都是基於Annotation,它們在編譯時動態生成代碼,它們之間會相互影響,一個出錯了,會導致Annotation編譯時中斷
相關

其實在官方也有說明,據說 V2 編譯器進行了更改,沒試過,項目aar打包 不敢擅動,需要gradle 3.1,加了這個感覺也是有點坑,error太多,不好找,希望能忽略不相關error

allprojects {
    afterEvaluate {
        tasks.withType(JavaCompile.class) {
            options.compilerArgs << "-Xmaxerrs" << "500"
        }
    }
}

與include 配合使用 databinding 沒有生成 include 文件控件變量
具體解決方案 將include佈局設置id,就會生成相關變量,使用的時候

databinding.<include佈局Id>.<佈局下相關控件>
和阿里的arouter路由框架一起使用

當編寫了好幾個代碼文件,其中一個Arouter的@Autowired定義的字段沒有能設置爲私有在編譯時,會讓人崩潰,所有的databingding文件全報錯,而獨獨真實的異常怎麼也找不到

Arouter 相關總結

傳值
arouter 很靈活,對他不是很瞭解的時候,不能發揮它最大的威力,傳值的時候不僅可以傳String還能傳對象

@Autowired
Object object;

'''''
Arouter.getInstance().inject(this);
'''

設置activity flag ,以及fragment不能設置startActivityForResult
默認只能設置一個flag,不知道是我不熟悉還是什麼原因,按道理寫框架的人不會犯這麼低級的錯誤

Postcard postcard = ARouter.getInstance().build(url);
LogisticsCenter.completion(postcard);
Class<?> destination = postcard.getDestination();

Intent intent = new Intent(getContext,destination);

LiveData

還沒發現什麼特別的地方,和RxJava一樣作爲響應式編程典範,都是訂閱者模式,LiveData優點來說是對界面生命週期的監聽,以及與databinding的適配,還有一點需要注意的是當界面不可見無法接收到事件,對於新註冊的Observe會返回前面所有的事件,俗稱:粘性事件;RxJava有着事件序列調度的優點

dagger2

Dagger2是Dagger的升級版,是一個依賴注入框架,第一代由大名鼎鼎的Square公司共享出來,依賴注入是面向對象編程的一種設計模式。
相關文章 重要概念
使用下來感覺是省去了一些生成對象的重複工作,所有的moudle(new 對象)都能被重複利用,和spring2.5以後的註解類有點類似。中間踩了不少坑。

學習成本

新人剛面對一個成熟dagger2編寫的項目,要理清裏面的脈絡需要花費一些時間

與databingding 一起使用,編譯異常時誤報

偶爾忘記加上一個@Inject ,導致一大堆的databinding類集體報找不到,解決方案是滑倒最底部會有異常提示

app 層組件使用到子組件的依賴

另外加上@Scope 作用域,讓問題很難排查,解決方案:檢查報錯組件所引用的對象是否有引用到子組件(Activity或者Fragment) 如果有把該module include到該component, 修改兩個依賴組件的 @Scope

同名返回值和方法名

這個儘量小心再小心,尤其容易出現在拷貝粘貼的時候迷..,解決方案:方法上添加重名註釋區分
@Named()

Lazy 和 Provider的區別

Lazy 的作用會在調用的時候初始化,下次get的時候會同一個對象
Provider 也是延遲加載,但是下次調用的時候會返回一個新的對象

Lazy<User> userLazy = null;
user = userLazy.get()
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章