看完这篇文章,LiveData的用法竟然还可以这样用?

本文主要内容:

  1. 作用介绍
  2. 核心类介绍
  3. 基本使用
  4. 源码分析
    – 横竖屏切换恢复
    – 后台销毁恢复

ViewModel的主要工作:

本身主要是一个数据维护工具
将数据维护的工作从Activity上剥离,提供一个储存数据环境,自身机制可以解决开发中,数据受Activity生命周期影响产生数据丢失的问题 (主要为横竖屏切换以及在后台被销毁)。
通常结合LiveData使用。

作为一个纯数据维护工具,可以加入到MVP架构中负责数据保存。
而官方推选作为AAC架构MVVM中的VM层。


ViewModel的主要类:

  • ViewModel (下称VM)
    数据储存类,架构的核心类。
    使用时,直接继承该类,根据需求选择重写onCleared()方法。
    如需在Activity被系统销毁后依然保存数据,定义一个参数为(SavedStateHandle)的构造方法,并将数据保存SavedStateHandle中。
    实际上通过SavedInstanceState存取

  • AndroidViewModel
    VM子类,维护了Application的引用,由架构中的SavedStateViewModelFactory创建时传入。
    同样,需要接收SavedStateHandle时,需要定义参数为 (Application, SavedStateHandle)的构造方法。

  • ViewModelStore
    用于保存VM,内部维护了一个用于储存VMHashMap
    一般情况下,直接使用本类创建实例。

  • ViewModelStoreOwner
    接口,实现该接口的类,表示自身能够向外提供VM
    androidx 的AppCompatActivity/Fragment实现了该接口。

  • ViewModelProvider
    VM的提供者,获取VM的基本入口。
    实际依赖ViewModelStore存取VMFactory生成/恢复VM

  • Factory
    接口,实现该接口的类主要用于创建VM实例。
    不建议直接实现该接口,除非你清楚框架内容和自己的需求。
    一般情况下,如果无需SavedStateHandle机制,可以使用AndroidViewModelFactory
    否则应该使用或继承SavedStateViewModelFactory


ViewModel的基本使用:

  • 一般使用:
// VM
class ViewModelA : ViewModel()
// AVM
class ViewModelB(app: Application) : AndroidViewModel(app)

// Activity/Fragment .onCreate中
override fun onCreate() {
  ...
  val provider = ViewModelProvider(this)
  val vmA = provider.get(ViewModelA::class.java)
  val vmB = provider.get(ViewModelB::class.java)
  ...
}

  • 接受 SavedStateHandle
// VM
class ViewModelC(
        val handle: SavedStateHandle
) : ViewModel()

// AVM
class ViewModelD(
        app: Application, 
        val handle: SavedStateHandle
) : AndroidViewModel(app)

  • 跨 Fragment 共享数据
    Fragment中直接以Activity作为ViewModel的Key
...
val provider = ViewModelProvider(requireActivity())
val vmA = provider.get(ViewModelA::class.java)

  • 通过 Application 创建全局共享的 VM
class App : Application(), ViewModelStoreOwner {
    private lateinit var mAppViewModelStore: ViewModelStore
    private lateinit var mFactory: ViewModelProvider.Factory

    override fun onCreate() {
        super.onCreate()
        mAppViewModelStore = ViewModelStore()
        mFactory = ViewModelProvider
                      .AndroidViewModelFactory
                      .getInstance(this)
    }

    override fun getViewModelStore(): ViewModelStore {
        return mAppViewModelStore
    }

    private fun getAppFactory(): ViewModelProvider.Factory {
        return mFactory
    }

    fun getAppViewModelProvider(activity: Activity): ViewModelProvider {
        val app = checkApplication(activity) as App
        return ViewModelProvider(app, app.getAppFactory())
    }

    fun getAppViewModelProvider(fragment: Fragment): ViewModelProvider {
        return getAppViewModelProvider(fragment.requireActivity())
    }

    private fun checkApplication(activity: Activity): Application {
        return activity.application
                ?: throw IllegalStateException(
                      "Your activity is not yet attached to the Application instance." + 
                      "You can't request ViewModel before onCreate call.")
    }
}


ViewModel的关键源码分析:

以下源码分析将会去除非相关代码以简化

  • ViewModelProvider 实现相关:

前面提到,ViewModelProvider的工作完全依赖传入的ViewModelStoreFactory,可以直接从构造方法得知:

ViewModelProvider.java
----------------------

private final Factory mFactory;
private final ViewModelStore mViewModelStore;

public ViewModelProvider(ViewModelStoreOwner owner) {
  this(owner.getViewModelStore(), 
        owner instanceof HasDefaultViewModelProviderFactory
        ? ((HasDefaultViewModelProviderFactory) owner)
            .getDefaultViewModelProviderFactory()
        : NewInstanceFactory.getInstance());
}

public ViewModelProvider(ViewModelStoreOwner owner, Factory factory) {
    this(owner.getViewModelStore(), factory);
}

public ViewModelProvider(ViewModelStore store, Factory factory) {
    mFactory = factory;
    mViewModelStore = store;
}

// 简单的反射创建实例的工厂
public static class NewInstanceFactory implements Factory {
    public <T extends ViewModel> T create(Class<T> modelClass) {
        return modelClass.newInstance()
    }
}

androidx.activity.ComponentActivityandroidx.fragment.app.Fragment都实现了ViewModelStoreOwnerHasDefaultViewModelProviderFactory接口。

public class AppCompatActivity extends FragmentActivity...{}
public class FragmentActivity extends ComponentActivity...{}

public class ComponentActivity extends ... implements
        ViewModelStoreOwner,
        HasDefaultViewModelProviderFactory,
        SavedStateRegistryOwner ... {}

public class Fragment implements 
        ViewModelStoreOwner, 
        HasDefaultViewModelProviderFactory, 
        SavedStateRegistryOwner ... {}

ViewModelProviderget()方法中返回<

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值