Jetpack是众多优秀组件的集合。是谷歌推出的一套引领Android开发者逐渐统一开发规范的架构
持有组件(如Activity Fragment)生命周期状态的信息的组件,并且允许其他对象观察此状态
import androidx.lifecycle.*
import java.util.concurrent.ConcurrentHashMap
object HiDataBus {
private val eventMap = ConcurrentHashMap<String, StickyLiveData<*>>()
fun <T> with(eventName: String): StickyLiveData<T> {
//基于事件名称 订阅、分发消息,
//由于 一个 livedata 只能发送 一种数据类型
//所以 不同的event事件,需要使用不同的livedata实例 去分发
var liveData = eventMap[eventName]
if (liveData == null) {
liveData = StickyLiveData<T>(eventName)
eventMap[eventName] = liveData
}
return liveData as StickyLiveData<T>
}
//通过一堆的反射,获取livedata当中的mversion字段,来控制黏性数据的分发与否,但是我们认为这种反射不够优雅。
class StickyLiveData<T>(private val eventName: String) : LiveData<T>() {
internal var mStickyData: T? = null
internal var mVersion = 0
fun setStickyData(stickyData: T) {
mStickyData = stickyData
setValue(stickyData)
//就是在主线程去发送数据
}
fun postStickyData(stickyData: T) {
mStickyData = stickyData
postValue(stickyData)
//不受线程的
}
override fun setValue(value: T) {
mVersion++
super.setValue(value)
}
override fun observe(owner: LifecycleOwner, observer: Observer<in T>) {
observerSticky(owner, false, observer)
}
fun observerSticky(owner: LifecycleOwner, sticky: Boolean, observer: Observer<in T>) {
//允许指定注册的观察则 是否需要关心黏性事件
//sticky =true, 如果之前存在已经发送的数据,那么这个observer会受到之前的黏性事件消息
owner.lifecycle.addObserver(LifecycleEventObserver { source, event ->
//监听 宿主 发生销毁事件,主动把livedata 移除掉。
if (event == Lifecycle.Event.ON_DESTROY) {
eventMap.remove(eventName)
}
})
super.observe(owner, StickyObserver(this, sticky, observer))
}
}
class StickyObserver<T>(
val stickyLiveData: StickyLiveData<T>,
val sticky: Boolean,
val observer: Observer<in T>
) : Observer<T> {
//lastVersion 和livedata的version 对齐的原因,就是为控制黏性事件的分发。
//sticky 不等于true , 只能接收到注册之后发送的消息,如果要接收黏性事件,则sticky需要传递为true
private var lastVersion = stickyLiveData.mVersion
override fun onChanged(t: T) {
if (lastVersion >= stickyLiveData.mVersion) {
//就说明stickyLiveData 没有更新的数据需要发送。
if (sticky && stickyLiveData.mStickyData != null) {
observer.onChanged(stickyLiveData.mStickyData)
}
return
}
lastVersion = stickyLiveData.mVersion
observer.onChanged(t)
}
}
}
api 'androidx.lifecycle:lifecycle-viewmodel-savedstate:2.2.0'
//获取操作数据库数据的dao对象
abstract val getCacheDao: CacheDao
}
import java.io.ByteArrayInputStream
import java.io.ByteArrayOutputStream
import java.io.ObjectInputStream
import java.io.ObjectOutputStream
object HiStorage {
fun <T> saveCache(key: String, body: T) {
val cache = Cache()
cache.key = key
cache.data = toByteArray(body)
CacheDatabase.get().cacheDao.saveCache(cache)
}
fun <T> getCache(key: String): T? {
val cache = CacheDatabase.get().cacheDao.getCache(key)
return (if (cache?.data != null) {
toObject(cache.data)
} else null) as? T
}
fun deleteCache(key: String) {
val cache = Cache()
cache.key = key
CacheDatabase.get().cacheDao.deleteCache(cache)
}
private fun <T> toByteArray(body: T): ByteArray? {
var baos: ByteArrayOutputStream? = null
var oos: ObjectOutputStream? = null
try {
baos = ByteArrayOutputStream()
oos = ObjectOutputStream(baos)
oos.writeObject(body)
oos.flush()
return baos.toByteArray()
} catch (e: Exception) {
e.printStackTrace()
} finally {
baos?.close()
oos?.close()
}
return ByteArray(0)
}
private fun toObject(data: ByteArray?): Any? {
var bais: ByteArrayInputStream? = null
var ois: ObjectInputStream? = null
try {
bais = ByteArrayInputStream(data)
ois = ObjectInputStream(bais)
return ois.readObject()
} catch (e: Exception) {
e.printStackTrace()
} finally {
bais?.close()
ois?.close()
}
return null
}
}
Lifecycle组件,Activity是如何实现宿主能力的?
ReportFragment注入,目的是为了兼容直接继承自Activity和自定义LifecycleOwner的场景
LiveData与传统消息订阅、分发组件的不同?
观察者不活跃(宿主不可见)不分发数据,避免无用的后台资源抢占
基于声明周期,可避免内存泄露、NPE等问题
ViewModel是如何实现复用的?
本质是ViewModelStroe对象以NonConfigurationInstances的形式被存储到ActivityClientRecord中,在页面重建后,又被传递到新的Activity对象中
savedState组件是如何实现数据复用的?
利用了onSaveInstanceState的被触发的时机,最终会存储到ActivityRecord对象中。页面重建后,又被传递到新的ViewModel对象中。
Room数据库如何设计一款通用的数据缓存组件?
把缓存数据二进制序列化,相比于JSON序列化效率更高,读取缓存时能直接还原成原本类型
ViewPager刷新不起作用的解决方案以及背后原理
getItemPosition(Object object)刷新前后,让我们自行决定object在Viewpager中的去留
getItemId(Int position)最好返回一个与位置无关的独一无二的id。可避免复用问题
首页模块还可以优化的地方
因篇幅问题不能全部显示,请点此查看更多更全内容
Copyright © 2019- nryq.cn 版权所有 赣ICP备2024042798号-6
违法及侵权请联系:TEL:199 1889 7713 E-MAIL:2724546146@qq.com
本站由北京市万商天勤律师事务所王兴未律师提供法律服务