android - 如何实现 LiveData 单例

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

我需要在 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/

相关文章:

android - Android 程序如何使用 NEON SIMD?

android - 哪个更好的解决方案获取服务器响应数据?

angularjs - 为什么 Angular 服务是单例?

java - 如何将单例引用传递给十个兄弟对象

ios - Objective C - 单例静态方法覆盖不适用于多个子类

android - 如何使用 VideoSupportFragment 在 TV Leanback 应用程序中捕获触摸事件以显示视频控件?

android - 错误 : ENOENT, 没有这样的文件或目录 - PhoneGap

inheritance - Kotlin 属性不能被子接口(interface)覆盖

android - 具有合成绑定(bind)和可空性的 Kotlin View

java - 如何将此排序映射方法从 java 转换为 Kotlin