如何实现LiveData Singleton

时间:2019-09-13 14:33:56

标签: android kotlin singleton android-architecture-components android-livedata

我需要在活动之间传递位图,而无需将图像写入内部/外部存储器。

一个Intent无法承载该大小,所以我发现最好的选择是使用Singleton位图或扩展Livedata并将其用作Singleton。 (我对体系结构不好,所以如果您有更好的解决方案...)

我正在尝试实现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示例:

在我的第一次活动中,我附加了观察者

    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")
    })

在第二个活动中,我将值设置为:

    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)
}

但是观察者永远不会触发,您确定我可以像这样创建Live Data单例吗?谢谢!

1 个答案:

答案 0 :(得分:2)

示例中的

StockManager只是出于示例目的而创建的随机自定义类。

为给您提供一个使用更熟悉的组件的简单示例,让我们想象一下,您需要创建一个自定义LiveData来计算(并发出计数){{1 }} 活跃。看起来可能像这样:

LiveData

并解释您的问题

  • 监听器将用于什么?

该侦听器将附加到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的值。

  • 什么是StockManager类?

只是一个示例类。

  • 如果仅需要用于位图,是否也需要使用onActive()和onInactive()?

不。实际上,我猜测您不需要LiveData来运输大型物体。正如您所指出的,您只需要一个简单的单例缓存类。如果您有LiveData的信息流,并且您希望活动自动对该信息流做出反应,那么LiveData就很有意义。例如:

Bitmap



修改: 这是该类的单例版本:

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>
}