面试题答案
一键面试LiveData感知数据变化并通知观察者的原理
- 数据变化感知:
- LiveData内部通过一个
mVersion
变量来记录数据版本。当调用setValue(T value)
(用于主线程)或postValue(T value)
(用于非主线程)方法更新数据时,mVersion
会自增。 - 观察者通过
observe
方法注册时,会携带一个LifecycleOwner
和一个Observer
。LiveData会将这些信息保存在内部的mObservers
集合中。
- LiveData内部通过一个
- 通知观察者:
- 当数据变化导致
mVersion
增加后,LiveData会遍历mObservers
集合。对于每个观察者,它会检查LifecycleOwner
的状态是否处于STARTED
或RESUMED
。如果是,且当前观察者的版本小于LiveData的版本(即observer.mLastVersion < mVersion
),则会调用观察者的onChanged
方法,将新的数据传递给观察者,从而实现通知。
- 当数据变化导致
创建LiveData对象并通知Activity或Fragment示例
- 创建LiveData对象:
- 首先,定义一个继承自
LiveData
的类,例如:
- 首先,定义一个继承自
class MyLiveData : LiveData<String>() {
fun updateData(newData: String) {
value = newData
}
}
- 或者使用
MutableLiveData
,它是LiveData
的一个子类,提供了公开的setValue
和postValue
方法,更加方便在ViewModel等地方使用。在ViewModel中使用如下:
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
class MyViewModel : ViewModel() {
val myLiveData: MutableLiveData<String> = MutableLiveData()
fun updateData(newData: String) {
myLiveData.value = newData
}
}
- 在Activity中观察LiveData:
import android.os.Bundle
import android.widget.TextView
import androidx.appcompat.app.AppCompatActivity
import androidx.lifecycle.Observer
import androidx.lifecycle.ViewModelProvider
class MainActivity : AppCompatActivity() {
private lateinit var viewModel: MyViewModel
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
viewModel = ViewModelProvider(this).get(MyViewModel::class.java)
val textView: TextView = findViewById(R.id.textView)
viewModel.myLiveData.observe(this, Observer { data ->
textView.text = data
})
viewModel.updateData("Hello, LiveData!")
}
}
- 在Fragment中观察LiveData:
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.TextView
import androidx.fragment.app.Fragment
import androidx.lifecycle.Observer
import androidx.lifecycle.ViewModelProvider
class MyFragment : Fragment() {
private lateinit var viewModel: MyViewModel
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
val view = inflater.inflate(R.layout.fragment_my, container, false)
viewModel = ViewModelProvider(this).get(MyViewModel::class.java)
val textView: TextView = view.findViewById(R.id.textView)
viewModel.myLiveData.observe(viewLifecycleOwner, Observer { data ->
textView.text = data
})
return view
}
}
在上述示例中,无论是Activity还是Fragment,通过 observe
方法注册观察者,并在LiveData数据变化时,更新UI显示的数据。