Jetpack之viewModel

289 阅读1分钟

使用起来很简单:新建一个类继承自ViewModel,在这里对数据进行获取

class UserViewModel : ViewModel() {

    private lateinit var users: MutableLiveData<List<User>>

    fun getUsers(): LiveData<List<User>> {
        if (!::users.isInitialized) {
            users = MutableLiveData()
            loadUsers()
        }
        return users
    }

    private fun loadUsers() {
        // Do an asynchronous operation to fetch users .
        Thread(Runnable {
            Thread.sleep(3000)
            // 由于在子线程发送值需要用 postValue , 否则用 setValue 就可以了。
            users.postValue(listOf(User("1", "AA"), User("2", "BB")))
        }).start()
    }
}

然后在fragment或者activity中直接使用这个model即可。

class MainActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
//        获取factory
        val factory: ViewModelProvider.Factory = ViewModelProvider.AndroidViewModelFactory.getInstance(application)
//        获取provider
        val provider = ViewModelProvider(this, factory)
//        获取viewModel
        val mViewModel=provider.get(UserViewModel::class.java)
//        观察viewModel的变化来更新UI
        mViewModel.getUsers().observe(this, Observer {
            Log.e(javaClass.simpleName,it.toString())
        })
    }
}

VIewModel是具有生命周期感知能力的,他之所以会做到这点是因为他每次获取viewModel都是从ViewModelStore中取,获取 ViewModel 使用的 key 相对具体的 ViewModel 类是不会变化的,因此从 ViewModelStore 中取出的 ViewModel 对象也不会变。包括在配置更改后也可以获取到之前的 ViewModel .这一点可以在fragmentActivity中看到相关代码,比如下面

@Override
protected void onDestroy() {
    super.onDestroy();

    if (mViewModelStore != null && !isChangingConfigurations()) {
        mViewModelStore.clear();
    }

    mFragments.dispatchDestroy();
}

在onDestroy时调用了MViewModelStore中的clear方法,这里才是ViewModel真正销毁的地方。因为ViewModelStore是存储某一个activity或者fragment中的所有ViewModel的。所以同一个activity的不同fragment之间的通信完全可以利用这个store,前提是获取viewModel时得利用activity来获取,这个才获得的是同一个store,从而可以共享store中的ViewModel