建设厅网站贵州人事考试信息网提供手机网站制作公司
news/
2025/10/2 5:21:18/
文章来源:
建设厅网站贵州人事考试信息网,提供手机网站制作公司,深圳百度代理,课件ppt免费下载目录 一、LiveData的基本使用1. 使用方式一2. 使用方式二3. 使用方式三 二、LiveData 去除黏性数据的方法1. 去除黏性的Java版本2. 去除黏性的Kotlin版本 一、LiveData的基本使用
1. 使用方式一
MyLiveData.kt
package com.example.mylivedata.simple1import androidx.lifec… 目录 一、LiveData的基本使用1. 使用方式一2. 使用方式二3. 使用方式三 二、LiveData 去除黏性数据的方法1. 去除黏性的Java版本2. 去除黏性的Kotlin版本 一、LiveData的基本使用
1. 使用方式一
MyLiveData.kt
package com.example.mylivedata.simple1import androidx.lifecycle.MutableLiveDataobject MyLiveData { // 单例// 懒加载val info : MutableLiveDataString by lazy { MutableLiveDataString() }
}MainActivity.kt
package com.example.mylivedata.simple1import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.widget.TextView
import androidx.lifecycle.Observer
import com.example.mylivedata.R
import kotlin.concurrent.threadclass MainActivity : AppCompatActivity() {override fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)setContentView(R.layout.activity_main)val textView : TextView findViewById(R.id.tv_textView)// TODO 1.观察者 环节MyLiveData.info.observe(this, ObserverString { t -textView.text t // 更新UI})// 完整写法 new Observer 重写onChange方法MyLiveData.info.observe(this, object : ObserverString {override fun onChanged(t: String?) {textView.text t // 更新UI}})// TODO 2.触发数据改变 环节MyLiveData.info.value default // setValue 主线程thread {Thread.sleep(3000)MyLiveData.info.postValue(三秒钟后修改了哦) // postValue 子线程}thread {Thread.sleep(6000)MyLiveData.info.postValue(六秒钟后修改了哦) // postValue 子线程}}
}2. 使用方式二
MyLiveData.kt
package com.example.mylivedata.simple2import androidx.lifecycle.MutableLiveDataobject MyLiveData { // 单例// 这里为data的MutableLiveData 懒加载初始化懒加载用到时才加载val data : MutableLiveDataString by lazy { MutableLiveDataString()}init {// data.value dafault // 违背 在子线程setValue(SetValue在主线程中执行)data.postValue(test) // 子线程 执行postValue(postValue在子线程中执行)}}MyServer.kt
package com.example.mylivedata.simple2import android.app.Service
import android.content.Intent
import android.os.IBinder
import android.util.Log
import kotlin.concurrent.thread// 模拟后台推送
class MyServer : Service() {override fun onBind(intent: Intent?): IBinder? nulloverride fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {thread {for ( x in 1 .. 1000) {Log.d(MyServer, 服务器给你推送消息(叮咚声响),消息内容是:${x})MyLiveData.data.postValue(服务器给你推送消息啦消息内容是:${x})Thread.sleep(2000) // 2秒推送一次}}return super.onStartCommand(intent, flags, startId)}
}MainActivity2.kt
package com.example.mylivedata.simple2import android.content.Intent
import android.os.Bundle
import android.util.Log
import android.widget.Button
import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity
import com.example.mylivedata.R
import java.util.*class MainActivity2 : AppCompatActivity() {override fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)setContentView(R.layout.activity_main2)// 启动服务val button findViewByIdButton(R.id.bt)button.setOnClickListener {startService(Intent(this, MyServer::class.java))Toast.makeText(this, 推送服务器启动成功, Toast.LENGTH_SHORT).show()}// 观察者 界面可见的情况下才能做事情MyLiveData.data.observe(this, androidx.lifecycle.Observer {Log.d(MyServer, 界面可见说明用户在查看列表界面啦更新信息列表UI界面:${it})Toast.makeText(this, 更新消息列表UI界面成功:${it}, Toast.LENGTH_SHORT).show()})}
}3. 使用方式三
该方式使用的是黏性数据 MyLiveData.kt
package com.example.mylivedata.simple3import androidx.lifecycle.MutableLiveDataobject MyLiveData {// 这里的data的MutableLiveData 懒加载初始化懒加载用到时才加载val data : MutableLiveDataString by lazy { MutableLiveDataString() }}MainActivity3.kt
package com.example.mylivedata.simple3import android.content.Intent
import android.os.Bundle
import android.widget.Button
import androidx.appcompat.app.AppCompatActivity
import com.example.mylivedata.Rclass MainActivity3 : AppCompatActivity() {override fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)setContentView(R.layout.activity_main3)val button findViewByIdButton(R.id.button)button.setOnClickListener {MyLiveData.data.value 我就是我不一样的烟火startActivity(Intent(this, MainActivity4::class.java))}}
}MainActivity4.kt
package com.example.mylivedata.simple3import android.os.Bundle
import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity
import androidx.lifecycle.Observer
import com.example.mylivedata.Rclass MainActivity4 : AppCompatActivity() {override fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)setContentView(R.layout.activity_main4)// 后观察数据居然能够收到 前面修改的数据这就是 数据黏性/*MyLiveData.data.observe(this, Observer {Toast.makeText(this, 观察者数据变化:${it}, Toast.LENGTH_SHORT).show()})*/MyLiveData.data.observe(this, object : ObserverString {override fun onChanged(t: String?) {Toast.makeText(thisMainActivity4, 观察者数据变化:$t, Toast.LENGTH_SHORT).show()}})// 此观察者 和handler没有区别一股脑的执行极端的情况可以用// 但是需要手动考虑释放工作//MyLiveData.data.observeForever { }}override fun onDestroy() {super.onDestroy()// 手动释放//MyLiveData.data.removeObserver()}
}二、LiveData 去除黏性数据的方法
1. 去除黏性的Java版本
OkLiveDataBusJava.java
package com.example.mylivedata.simple4;import androidx.annotation.NonNull;
import androidx.arch.core.internal.SafeIterableMap;
import androidx.lifecycle.LifecycleOwner;
import androidx.lifecycle.LiveData;
import androidx.lifecycle.MutableLiveData;
import androidx.lifecycle.Observer;import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;/*** 单例模式 去掉粘性事件 Java版本*/
public class OkLiveDataBusJava {// 存放订阅者private MapString, BusMutableLiveDataObject bus;private static OkLiveDataBusJava liveDataBus new OkLiveDataBusJava();private OkLiveDataBusJava() {bus new HashMap();}public static OkLiveDataBusJava getInstance() {return liveDataBus;}// 注册订阅者public synchronized T BusMutableLiveDataT with(String key, ClassT type) {if (bus.containsKey(key)) {bus.put(key, new BusMutableLiveData());}return (BusMutableLiveDataT) bus.get(key);}public static class BusMutableLiveDataT extends MutableLiveDataT {Overridepublic void observe(NonNull LifecycleOwner owner, NonNull Observer? super T observer) {super.observe(owner, observer); // 启用系统的功能不写就破坏了hook(observer);}private void hook(Observer? super T observer) {try {// TODO 1.得到mLastVersion// 获取到LiveData类中的mObservers对象ClassLiveData liveDataClass LiveData.class;Field mObserversField liveDataClass.getDeclaredField(mObservers);mObserversField.setAccessible(true);// 获取到这个成员变量的对象Object mObserversObject mObserversField.get(this);// 得到map对象的class对象 private SafeIterableMapObserver? super T, ObserverWrapper mObservers new SafeIterableMap();Class? mObserversClass mObserversObject.getClass();// 获取到mObservers对象的get方法Method get mObserversClass.getDeclaredMethod(get, Object.class);get.setAccessible(true);// 执行get方法Object invokeEntry get.invoke(mObserversObject, observer);// 取到entry中的valueObject observerWrapper null;if (invokeEntry ! null invokeEntry instanceof Map.Entry) {observerWrapper ((Map.Entry) invokeEntry).getValue();}if (observerWrapper null) {throw new NullPointerException(observerWrapper is null);}// 得到observerWrapper的类对象// observerWrapper.getClass() 获取的是LifecycleBoundObserver类对象// observerWrapper类是LifecycleBoundObserver类的父类Class? supperClass observerWrapper.getClass().getSuperclass();Field mLastVersion supperClass.getDeclaredField(mLastVersion);mLastVersion.setAccessible(true);// TODO 2.得到mVersionField mVersion liveDataClass.getDeclaredField(mVersion);mVersion.setAccessible(true);// TODO 3.mLastVersion mVersionObject mVersionValue mVersion.get(this);mLastVersion.set(observerWrapper, mVersionValue);} catch (Exception e) {e.printStackTrace();}}}
}
2. 去除黏性的Kotlin版本
OKLiveDataBusKT.kt
package com.example.mylivedata.simple4import android.util.Log
import androidx.lifecycle.LifecycleOwner
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.Observer
import java.lang.NullPointerException
import java.lang.reflect.Field
import java.lang.reflect.Method/*** 单例模式 去掉黏性事件有关闭黏性的开关KT版本*/
object OKLiveDataBusKT {// 存放订阅者private val bus : MutableMapString, BusMutableLiveDataAny by lazy { HashMapString, BusMutableLiveDataAny() }// 暴露一个函数给外界注册订阅者关系fun T with(key : String, type : ClassT, isStack : Boolean true) : BusMutableLiveDataT {if (!bus.containsKey(key)) {bus[key] BusMutableLiveData(isStack)}return bus[key] as BusMutableLiveDataT}class BusMutableLiveDataT private constructor() : MutableLiveDataT() {var isStack : Boolean false// 次构造constructor(isStack: Boolean) : this() {this.isStack isStack}override fun observe(owner: LifecycleOwner, observer: Observerin T) {super.observe(owner, observer)if (!isStack) {hook(observer)Log.d(abc, Kotlin版本 不启用黏性)} else {Log.d(abc, Kotlin版本 启用黏性)}}private fun hook(observer: Observerin T) {// TODO 1.得到mLastVersion// 获取到LiveData的类中的mObservers对象val liveDataClass LiveData::class.javaval mObserversField liveDataClass.getDeclaredField(mObservers)mObserversField.isAccessible true // 私有修饰可以访问// 获取到这个成员变量的对象 Kotlin Any Java Objectval mObserversObject : Any mObserversField.get(this)// 得到map对象的class对象 private SafeIterableMapObserver? super T, ObserverWrapper mObservers new SafeIterableMap();val mObserversClass : Class* mObserversObject.javaClass// 获取到mObservers对象的get方法 protected EntryK, V get(K k)val get : Method mObserversClass.getDeclaredMethod(get, Any::class.java)get.isAccessible true // 私有修饰也可以访问// 执行get方法val invokeEntry : Any get.invoke(mObserversObject, observer)// 取到entry中的valuevar observerWrapper : Any? nullif (invokeEntry ! null invokeEntry is Map.Entry*, *) {observerWrapper invokeEntry.value}if (observerWrapper null) {throw NullPointerException(observerWrapper is null)}// 得到observerWrapper的类对象val supperClass : Class* observerWrapper.javaClass.superclassval mLastVersion : Field supperClass.getDeclaredField(mLastVersion)mLastVersion.isAccessible true// TODO 2.得到mVersionval mVersion : Field liveDataClass.getDeclaredField(mVersion)mVersion.isAccessible true// TODO 3.mLastVersion mVersionval mVersionValue mVersion.get(this)mLastVersion.set(observerWrapper, mVersionValue)}}
}MainActivity.kt
package com.example.mylivedata.simple4import android.content.Intent
import android.os.Bundle
import android.widget.Button
import androidx.appcompat.app.AppCompatActivity
import com.example.mylivedata.Rclass MainActivity : AppCompatActivity() {override fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)setContentView(R.layout.activity_main)// LiveData发生消息通知所有的观察者数据变化了// KT版本 旧数据 黏性数据OKLiveDataBusKT.with(data1, String::class.java).value liveData kotlin数据// Java版本OkLiveDataBusJava.getInstance().with(data2, String::class.java).value livaData java数据// 点击事件跳转到下一个Activityval button findViewByIdButton(R.id.button)button.setOnClickListener {startActivity(Intent(this, MainActivity2::class.java))}}
}MainActivity2.kt
package com.example.mylivedata.simple4import android.os.Bundle
import android.util.Log
import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity
import androidx.lifecycle.Observer
import com.example.mylivedata.R
import kotlin.concurrent.threadclass MainActivity2 : AppCompatActivity() {override fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)setContentView(R.layout.activity_main2)// Kotlin版本订阅观察者OKLiveDataBusKT.with(data1, String::class.java).observe(this, Observer(){Toast.makeText(this, Kotlin版本的观察者:${it}, Toast.LENGTH_SHORT).show()Log.d(abc, Kotlin版本的观察者:${it})})// Java版本订阅观察者Java是模拟剔除黏性的OkLiveDataBusJava.getInstance().with(data2, String::class.java).observe(this, Observer() {Toast.makeText(this, Java版本的观察者:${it}, Toast.LENGTH_SHORT).show()Log.d(abc, Java版本的观察者:${it})})thread {Thread.sleep(2000)OKLiveDataBusKT.with(data1, String::class.java).postValue(2222)}thread {Thread.sleep(4000)OkLiveDataBusJava.getInstance().with(data2, String::class.java).postValue(4444)}}
}
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/924572.shtml
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!