Android Studio 默认生成的代码一般是这样的:
package com.messy.lingplayer.playui
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.fragment.app.Fragment
import androidx.lifecycle.ViewModelProviders
import com.messy.lingplayer.R
import com.messy.lingplayer.SharedViewModel
class PlayUiFragment : Fragment() {
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
return inflater.inflate(R.layout.play_ui_fragment, container, false)
}
override fun onActivityCreated(savedInstanceState: Bundle?) {
super.onActivityCreated(savedInstanceState)
viewModel = ViewModelProviders.of(this).get(SharedViewModel::class.java)
// TODO: Use the ViewModel
}
private lateinit var viewModel: SharedViewModel
companion object {
fun newInstance() = PlayUiFragment()
}
}
关键在于这一句
viewModel = ViewModelProviders.of(this).get(SharedViewModel::class.java)
其中 ViewModelProviders.of(this)表示将 viewModel 绑定到这个 Fragment 的生命周期(这里的 this 便表示当前的 Fragment 对象)我们可以将 this 改为 activity,即将 viewModel 绑定到 Fangment 所在的 Activity 的生命周期上,即
viewModel = ViewModelProviders.of(activity!!).get(SharedViewModel::class.java)
然后再相应的 Activity 中绑定 SharedViewModel:
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
viewModel = ViewModelProviders.of(this).get(SharedViewModel::class.java)
initMediaBrowser()
initView()
}
那么便可在 Activity 的整个生命周期之内和多个 Fragment 共享资源
原理
ViewModel 的生命周期依赖于对应的 Activity 或 Fragment 的生命周期。通常会在 Activity 第一次 onCreate()时创建 ViewModel,ViewModel 的生命周期一直持续到 Activity 最终销毁或 Frament 最终 detached,期间由于屏幕旋转等配置变化引起的 Activity 销毁重建并不会导致 ViewModel 重建。借用官方示意图来解释一下:
这样就可以避免在 Activity 直接利用接口进行回调