天天看点

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();
}