我需要在 Activity 之间传递位图而不将图像写入内部/外部存储器。
Intent 不能承载该大小,因此我发现的最佳选择是使用单例位图或扩展 Livedata 并将其用作单例。 (我不太擅长架构,所以如果您有更好的解决方案...)
我正在尝试实现 LiveData 选项,因为实时数据观察器会很有用,而且我正在关注 official documentation :
class StockLiveData(symbol: String) : LiveData<BigDecimal>() {
private val stockManager: StockManager = StockManager(symbol)
private val listener = { price: BigDecimal ->
value = price
}
override fun onActive() {
stockManager.requestPriceUpdates(listener)
}
override fun onInactive() {
stockManager.removeUpdates(listener)
}
companion object {
private lateinit var sInstance: StockLiveData
@MainThread
fun get(symbol: String): StockLiveData {
sInstance = if (::sInstance.isInitialized) sInstance else StockLiveData(symbol)
return sInstance
}
}
但是我真的不明白其中的逻辑:
- 监听器的用途是什么?
- StockManager 类是什么?
- 如果我只需要一个位图,我还需要使用 onActive() 和 onInactive() 吗?
我在任何地方都找不到不同的实现示例,我如何才能只为位图实现它?
------------ 更新 Sanlok Lee 的回答----------------
我尝试实现您的类 BitmapCache 示例:
在我的第一个 Activity 中,我附加了观察者
companion object {
val myCache = BitmapCache()
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.mylayout)
myCache.getCachedBitmap().observe(this, Observer<Bitmap> { selfie: Bitmap? ->
Log.i(TAG, "TRIGGERED")
})
在我的第二个 Activity 中,我设置了这样的值:
companion object {
val myCache = BitmapCache()
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.mylayout)
val bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.android)
Handler().postDelayed({
myCache.cacheBitmap(bitmap)
}, 3000)
}
但是观察者永远不会被触发,你确定我可以创建一个这样的实时数据单例吗?谢谢!
最佳答案
示例中的
StockManager
只是他们为示例目的而制作的随机自定义类。
只是为了给您一个使用更熟悉的组件的更简单的示例,让我们假设您需要创建一个自定义 LiveData
来计算(并发出计数)用户按钮按下的次数LiveData
处于 Activity 状态。它可能看起来像这样:
class ButtonClickLiveData(val button: Button) : LiveData<Int>() {
var clickCount = 0
private val listener = { v: View ->
clickCount++
value = clickCount
}
override fun onActive() {
// Set the click listener when LiveData is not active.
button.setOnClickListener(listener)
}
override fun onInactive() {
// Remove the click listener when LiveData is not active.
button.setOnClickListener(null)
}
}
并解释你的问题
- 监听器的用途是什么?
该监听器将附加到 StockManager
。当StockManager
有任何变化时,StockManager
类负责调用这个监听器,当监听器被调用时,它会更新LiveData
值.
- StockManager 类是什么?
只是一个示例类。
- 如果我只需要一个位图,我还需要使用 onActive() 和 onInactive() 吗?
没有。事实上,我猜你不需要 LiveData
来传输大对象。正如您所指出的,您只需要一个简单的单例缓存类。如果您有 Bitmap
流并且您希望 Activity 自动对流使用react,则 LiveData
会很有意义。例如:
class BitmapCache { // This can be a singleton class.
private val bitmapLiveData = MutableLiveData<Bitmap>()
fun cacheBitmap(bmp: Bitmap) {
bitmapLiveData.value = bmp
}
fun getCachedBitmap(): LiveData<Bitmap> = bitmapLiveData as LiveData<Bitmap>
}
编辑: 这是该类的单例版本:
object BitmapCache {
private val bitmapLiveData = MutableLiveData<Bitmap>()
fun cacheBitmap(bmp: Bitmap) {
bitmapLiveData.value = bmp
}
fun getCachedBitmap(): LiveData<Bitmap> = bitmapLiveData as LiveData<Bitmap>
}
它可以像这样使用:
// Activity A
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.mylayout)
BitmapCache.getCachedBitmap().observe(this, Observer<Bitmap> { selfie: Bitmap? ->
Log.i(TAG, "TRIGGERED")
})
// Activity B
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.mylayout)
val bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.android)
Handler().postDelayed({
BitmapCache.cacheBitmap(bitmap)
}, 3000)
}
关于android - 如何实现 LiveData 单例,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57925634/