LiveData那些事情,看我一篇就够了
一.LiveDataBus事件总线封装
方案一:只支持粘性
object LiveDataBus {
private val mBus = hashMapOf<String, SingleLiveData<Any>>()
fun <T>with(channel: String): SingleLiveData<T> {
if (!mBus.containsKey(channel)) {
mBus[channel] = SingleLiveData()
}
return mBus[channel]!! as SingleLiveData<T>
}
class SingleLiveData<T> : MutableLiveData<T>() {
val mPending= AtomicBoolean(false)
override fun observe(owner: LifecycleOwner, observer: Observer<in T>) {
super.observe(owner) { t ->
if (mPending.compareAndSet(true, false)) {
observer.onChanged(t)
}
}
}
override fun setValue(value: T?) {
mPending.set(true)
super.setValue(value)
}
fun clean(){
setValue(null)
}
}
}
方案二:粘性和非粘性
object LiveDataBus2{
private val bus: MutableMap<String, BusMutableLiveData<Any>> = mutableMapOf()
fun <T> with(key: String): BusMutableLiveData<T> {
if (!bus.containsKey(key)) {
bus[key] = BusMutableLiveData()
}
return bus[key] as BusMutableLiveData<T>
}
class BusMutableLiveData<T> : MutableLiveData<T>() {
private val observerMap: MutableMap<Observer<*>, Observer<*>> = mutableMapOf()
fun observeSticky(
owner: () -> Lifecycle,
observer: (T) -> Unit
) {
super.observe(owner, observer)
}
fun observeForeverSticky(observer: Observer<in T>) {
super.observeForever(observer)
}
override fun observeForever(observer: Observer<in T>) {
if (!observerMap.containsKey(observer)) {
observerMap[observer] = ObserverWrapper(observer)
}
super.observeForever(observerMap[observer] as Observer<in T>)
}
override fun removeObserver(observer: Observer<in T>) {
val realObserver: Observer<in T> =
if (observerMap.containsKey(observer)) {
observerMap.remove(observer) as Observer<in T>
} else {
observer
}
super.removeObserver(realObserver)
}
override fun observe(
owner: LifecycleOwner,
observer: Observer<in T>
) {
super.observe(owner, observer)
try {
hook(observer)
} catch (e: Exception) {
e.printStackTrace()
}
}
/**
* 利用反射将 LiveData 的 mVersion 赋值给 ObserverWrapper 的 mLastVersion
*/
@Throws(Exception::class)
private fun hook(observer: Observer<*>) {
// Get wrapper's version.
val liveDataClass = LiveData::class.java
// SafeIterableMap<Observer<? super T>, ObserverWrapper> mObservers
val observersField = liveDataClass.getDeclaredField("mObservers")
observersField.isAccessible = true
val observers = observersField[this]
val observersClass: Class<*> = observers.javaClass
// It's mObservers's get method.
val methodGet = observersClass.getDeclaredMethod("get", Any::class.java)
methodGet.isAccessible = true
val observerWrapperEntry = methodGet.invoke(observers, observer)
var observerWrapper: Any? = null
if (observerWrapperEntry is Map.Entry<*, *>) {
// Now we got observerWrapper.
observerWrapper = observerWrapperEntry.value
}
if (observerWrapper == null) {
throw NullPointerException("Wrapper can not be null!")
}
val observerWrapperParentClass: Class<*>? = observerWrapper.javaClass.superclass
val lastVersionField = observerWrapperParentClass!!.getDeclaredField("mLastVersion")
lastVersionField.isAccessible = true
// Get livedata's version.
val versionField = liveDataClass.getDeclaredField("mVersion")
versionField.isAccessible = true
val version = versionField[this]
// Set wrapper's version.
lastVersionField[observerWrapper] = version
}
}
private class ObserverWrapper<T>(val observer: Observer<T>) : Observer<T> {
override fun onChanged(t: T) {
if (isCallOnObserverForever()) {
return
}
observer.onChanged(t)
}
private fun isCallOnObserverForever(): Boolean {
val stackTrace = Thread.currentThread().stackTrace
for (element in stackTrace) {
if ("androidx.lifecycle.LiveData" == element.className
&& "observeForever" == element.methodName
) {
return true
}
}
return false
}
}
}
发送数据:
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
//发送数据
LiveDataBus2.with<String>("from_main")
.value = "From MainActivity."
//发送数据
LiveDataBus.with<String>("from_main")
.value = "From MainActivity111."
}
fun tiao(view: View) {
val intent = Intent(this, MainActivity2::class.java)
startActivity(intent)
}
}
接受数据:
class MainActivity2 : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main2)
LiveDataBus2.with<String>("from_main")
.observe(this::getLifecycle) {
Log.e("ytx", it)
}
LiveDataBus.with<String>("from_main")
.observe(this::getLifecycle) {
Log.e("ytx", it)
}
}
}
总结:方案2要比方案1功能更全。支持粘性和非粘性
二.LiveDataBus数据倒灌/粘性数据问题解决
参考文章
屏幕旋后转打印2次
class MainActivity3 : AppCompatActivity() {
val networkData = MutableLiveData<String>()
init {
networkData.value = "hahaha" //
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main3)
networkData.observe(this){
Log.d("ytx", "数据: ")
}
}
}
三.第三方:UnPeekLiveData
github搜索