天天看點

Android:我在學習MVVM+Architecture架構

學習

 1、【奇技淫巧】android studio 使用 includeBuild

 2、  Android studio code template個性化設定

3、除了會使用Json、xml, 如何使用ProtoBuf 在Android的使用與原了解析

4、GitHub 的 Fork 是什麼意思

5、經濟基礎決定上層建築之思考

6、坑:lifecycleScope不能在Activity下使用,使用androidX的AppCompatActivity()

學習項目1:https://github.com/wenfujing/MvvmArchitecture

學習項目2:https://github.com/wenfujing/MVVM-Architecture

Android Architecture Components是Google釋出的一套新的架構元件,使App的架構更加健壯,後面簡稱AAC  --學習

為何要使用MVVM架構呢 

引入美團技術團隊的一段解釋:

  1. 雙向綁定、資料驅動

    在正常的開發模式中,資料變化需要更新UI的時候,需要先擷取UI控件的引用,然後再更新UI。擷取使用者的輸入和操作也需要通過UI控件的引用。在MVVM中,這些都是通過資料驅動來自動完成的,資料變化後會自動更新UI,UI的改變也能自動回報到資料層,資料成為主導因素。這樣MVVM層在業務邏輯進行中隻要關心資料,不需要直接和UI打交道,在業務處理過程中簡單友善很多。

  2. 高度解耦

    MVVM模式中,資料是獨立于UI的。

    資料和業務邏輯處于一個獨立的ViewModel中,ViewModel隻需要關注資料和業務邏輯,不需要和UI或者控件打交道。UI想怎麼處理資料都由UI自己決定,ViewModel不涉及任何和UI相關的事,也不持有UI控件的引用。即便是控件改變了(比如:TextView換成EditText),ViewModel也幾乎不需要更改任何代碼。它非常完美的解耦了View層和ViewModel,解決了上面我們所說的MVP的痛點。

  3. 可複用、易測試、友善協同開發

    一個ViewModel可以複用到多個View中。同樣的一份資料,可以提供給不同的UI去做展示。對于版本疊代中頻繁的UI改動,更新或新增一套View即可。如果想在UI上做A/B Testing,那MVVM是你不二選擇。

    MVVM的分工是非常明顯的,由于View和ViewModel之間是松散耦合的:一個是處理業務和資料、一個是專門的UI處理。是以,完全由兩個人分工來做,一個做UI(XML和Activity)一個寫ViewModel,效率更高

    ViewModel層做的事是資料處理和業務邏輯,View層中關注的是UI,兩者完全沒有依賴。不管是UI的單元測試還是業務邏輯的單元測試,都是低耦合的。在MVVM中資料是直接綁定到UI控件上(部分資料是可以直接反映出UI上的内容),那麼我們就可以直接通過修改綁定的資料源來間接做一些Android UI上的測試。

  • 生命周期管理庫 - Lifecycle
    • Lifecycle元件,為下面兩個元件提供了生命周期感覺的基礎
    • LiveData元件,可觀測的、可感覺生命周期的資料
    • ViewModel元件,不依賴于View、提供UI資料、橋接持久層、業務邏輯
  • 資料持久化庫 - Room,Sqlite的ORM

項目位址:https://github.com/xykjlcx/OneArticleDemo

onSaveInstanceState()支援少量資料的,支援序列化資料,支援持久化資料

viewmodel :不支援持久化的資料,當頁面銷毀,viewmodel儲存資料就會清除。

BindAdapter是基于APT注解技術的,APT可以在項目代碼建構的時候,根據相關編寫規則,生成特定代碼,完成指定功能。BindAdapter提供了一個高自由的切片程式設計能力,允許在xml解析是綁定擴充行為,可以完成事件監聽,屬性指派,類型轉換,統一業務處理,比如埋點處理,防重按等,BindAdapter是DataBinding使用較多的注解,還有雙向標明,雙向指派等

<ImageView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:src="@{"http://****/**.jpg"}" />
           
@BindingAdapter("android:src")
    public static void setSrc(ImageView view, String bitmapPath) {
        if(ObjectUtil.nonNull(bitmapPath)) {
            GlideApp.with(view.getContext())
                    .load(bitmapPath)
                    .into(view);
        } else {
            view.setImageDrawable(null);
        }
    }
           

學習自《https://xiaozhuanlan.com/topic/1592867304》

Jetpack 架構元件本質:

Lifecycle 的本質是解決 “生命周期管理” 的一緻性問題

LiveData 的本質是解決 “跨域消息同步” 的一緻性問題

ViewModel 的本質是解決 “狀态儲存恢複” 的一緻性問題

DataBinding 的本質是解決 “視圖執行個體的 null 安全” 的一緻性問題

Navigation 的本質是解決 “路由初始參數恢複” 的一緻性問題

使用Room官方示例(Room是一個持久化工具,和ormlite、greenDao類似,都是ORM工具。在開發中我們可以利用Room來操作sqlite資料庫)

// User.java
@Entity
public class User {
    @PrimaryKey
    private int uid;

    @ColumnInfo(name = "first_name")
    private String firstName;

    @ColumnInfo(name = "last_name")
    private String lastName;

    // Getters and setters are ignored for brevity,
    // but they're required for Room to work.
}

// UserDao.java
@Dao
public interface UserDao {
    @Query("SELECT * FROM user")
    List<User> getAll();

    @Query("SELECT * FROM user WHERE uid IN (:userIds)")
    List<User> loadAllByIds(int[] userIds);

    @Query("SELECT * FROM user WHERE first_name LIKE :first AND "
           + "last_name LIKE :last LIMIT 1")
    User findByName(String first, String last);

    @Insert
    void insertAll(User... users);

    @Delete
    void delete(User user);
}

// AppDatabase.java
@Database(entities = {User.class}, version = 1)
public abstract class AppDatabase extends RoomDatabase {
    public abstract UserDao userDao();
}