将数据从生命周期观察者 class 传递到 Activity

Passing data from a class which is Lifecycle observer to the Activity

我有一个 class BatteryInfo,它是一个 life-cycle observer,在这个 class 中,有一个 BroadCastReceiver 负责获取所有电池信息。这个 class 与我调用它的 Activity 的 生命周期完美配合。这意味着它正在 注册广播 activity 创建 取消注册 activity。但是我很困惑如何在Activity.

中访问这个广播直播信息
class BatteryInfo(
        private val _context: Context,
        private val _lifecycle: Lifecycle,
    ): LifecycleObserver {

        private var _enabled = false

        init {
            _lifecycle.addObserver(this)
        }

        private val broadcastBatteryInfoListener = object : BroadcastReceiver() {

            override fun onReceive(context: Context?, intent: Intent?) {

                intent?.let {

                    val level = it.getIntExtra(BatteryManager.EXTRA_LEVEL, -1)
                    val temperature = it.getIntExtra(BatteryManager.EXTRA_TEMPERATURE, -1)
                    val voltage = it.getIntExtra(BatteryManager.EXTRA_VOLTAGE, -1)
                    val technology = it.getIntExtra(BatteryManager.EXTRA_TECHNOLOGY, -1)
                    val plugged = it.getIntExtra(BatteryManager.EXTRA_PLUGGED, -1)
                    val health = it.getIntExtra(BatteryManager.EXTRA_HEALTH, -1)



                  //  Log.d("TAG", String.format("%.1f", voltage / 1000f) + " V")
                }
            }
        }


        @OnLifecycleEvent(Lifecycle.Event.ON_START)
        fun start() {
          //  if (_enabled) {
                _context.registerReceiver(broadcastBatteryInfoListener,
                    IntentFilter(Intent.ACTION_BATTERY_CHANGED)
                )
          // }
        }

        @OnLifecycleEvent(Lifecycle.Event.ON_STOP)
        fun stop() {
            _context.unregisterReceiver(broadcastBatteryInfoListener)
        }

        @OnLifecycleEvent(Lifecycle.Event.ON_DESTROY)
        fun destroy() {
            _lifecycle.removeObserver(this)
        }


        // connect if not connected
        fun enable() {
            _enabled = true

            if (_lifecycle.currentState.isAtLeast(Lifecycle.State.STARTED)) {
                start()
            }
        }
    }

我正在从 MainActivity onCreate 方法中调用这个 class 像这样

BatteryInfo(this, lifecycle)

一个简单的侦听器就可以工作:

data class Stats(val level : Int,
                 val temp : Int,
                 val voltage : Int,
                 val technology : Int,
                 val plugged : Int,
                 val health : Int)


class BatteryInfo(
    private val _context: Context,
    private val _lifecycle: Lifecycle
): LifecycleObserver {

    private var _enabled = false
    private var listener: ((Stats) -> Unit)? = null

    init {
        _lifecycle.addObserver(this)
    }

    private val broadcastBatteryInfoListener = object : BroadcastReceiver() {

        override fun onReceive(context: Context?, intent: Intent?) {

            intent?.let {

                val level = it.getIntExtra(BatteryManager.EXTRA_LEVEL, -1)
                val temperature = it.getIntExtra(BatteryManager.EXTRA_TEMPERATURE, -1)
                val voltage = it.getIntExtra(BatteryManager.EXTRA_VOLTAGE, -1)
                val technology = it.getIntExtra(BatteryManager.EXTRA_TECHNOLOGY, -1)
                val plugged = it.getIntExtra(BatteryManager.EXTRA_PLUGGED, -1)
                val health = it.getIntExtra(BatteryManager.EXTRA_HEALTH, -1)

                listener?.invoke(Stats(level, temperature, voltage, technology, plugged, health))
                //  Log.d("TAG", String.format("%.1f", voltage / 1000f) + " V")
            }
        }
    }

    fun setListener(listener: ((Stats) -> Unit)?) {
        this.listener = listener
    }

    @OnLifecycleEvent(Lifecycle.Event.ON_START)
    fun start() {
        //  if (_enabled) {
        _context.registerReceiver(broadcastBatteryInfoListener,
            IntentFilter(Intent.ACTION_BATTERY_CHANGED)
        )
        // }
    }

    @OnLifecycleEvent(Lifecycle.Event.ON_STOP)
    fun stop() {
        _context.unregisterReceiver(broadcastBatteryInfoListener)
    }

    @OnLifecycleEvent(Lifecycle.Event.ON_DESTROY)
    fun destroy() {
        _lifecycle.removeObserver(this)
        listener = null
    }


    // connect if not connected
    fun enable() {
        _enabled = true

        if (_lifecycle.currentState.isAtLeast(Lifecycle.State.STARTED)) {
            start()
        }
    }
}

class SomeActivity : AppCompatActivity(){

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        BatteryInfo(this, lifecycle)
            .apply { setListener { stats: Stats -> Log.d(TAG, stats.toString()) } }

    }
}

我是在 MutableLiveData 和 LiveData 的帮助下完成的,但我不确定它是完美的解决方案还是hacky 解决方案。我想做一个完美的解决方案,遵循 MVVMclean-architectureSOLID principle创建多个对象,因为它非常昂贵。

 class BatteryInfo(
            private val _context: Context,
            private val _lifecycle: Lifecycle
        ) : LifecycleObserver {

            val map = HashMap<String, Int>()
            private var _enabled = false
            private val _batteryInfoMap = MutableLiveData<HashMap<String, Int>>()

            val batteryInfo: LiveData<HashMap<String, Int>>
                get() = _batteryInfoMap

            init {
                _lifecycle.addObserver(this)
            }

            private val broadcastBatteryInfoListener = object : BroadcastReceiver() {

                override fun onReceive(context: Context?, intent: Intent?) {

                    intent?.let {

                        val level = it.getIntExtra(BatteryManager.EXTRA_LEVEL, -1)
                        val temperature = it.getIntExtra(BatteryManager.EXTRA_TEMPERATURE, -1)
                        val voltage = it.getIntExtra(BatteryManager.EXTRA_VOLTAGE, -1)
                        val technology = it.getIntExtra(BatteryManager.EXTRA_TECHNOLOGY, -1)
                        val plugged = it.getIntExtra(BatteryManager.EXTRA_PLUGGED, -1)
                        val health = it.getIntExtra(BatteryManager.EXTRA_HEALTH, -1)

                        map["level"] = level
                        map["temperature"] = temperature

                        _batteryInfoMap.value = map
                    }
                }
            }


            @OnLifecycleEvent(Lifecycle.Event.ON_START)
            fun start() {
                if (_enabled) {
                    _context.registerReceiver(
                        broadcastBatteryInfoListener,
                        IntentFilter(Intent.ACTION_BATTERY_CHANGED)
                    )
                }
            }

            @OnLifecycleEvent(Lifecycle.Event.ON_STOP)
            fun stop() {
                _context.unregisterReceiver(broadcastBatteryInfoListener)
            }

            @OnLifecycleEvent(Lifecycle.Event.ON_DESTROY)
            fun destroy() {
                _lifecycle.removeObserver(this)
            }

            fun enable() {
                _enabled = true

                if (_lifecycle.currentState.isAtLeast(Lifecycle.State.STARTED)) {
                    start()
                }
            }
        }

并在 MainActivity 内部 onCreate()

override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        val into = BatteryInfo(this, lifecycle)
        into.enable()

        into.batteryInfo.observe(this, Observer {
            Log.d("TAG", "${it.values}")

        })
    }

我知道这不是您的回答,而是一种不同的完成任务的方法。它还会删除所有样板代码。

您可以使用对象从 intent 中提取所有数据,并 return 数据实例 class。 在此处阅读有关 kotlin 中的对象的更多信息 - https://kotlinlang.org/docs/tutorials/kotlin-for-py/objects-and-companion-objects.html

object BatteryInfoUtils {

      fun getBatteryInfoFromIntent(intent: Intent): Stats { intent?.let {

                    val level = it.getIntExtra(BatteryManager.EXTRA_LEVEL, -1)
                    val temperature = it.getIntExtra(BatteryManager.EXTRA_TEMPERATURE, -1)
                    val voltage = it.getIntExtra(BatteryManager.EXTRA_VOLTAGE, -1)
                    val technology = it.getIntExtra(BatteryManager.EXTRA_TECHNOLOGY, -1)
                    val plugged = it.getIntExtra(BatteryManager.EXTRA_PLUGGED, -1)
                    val health = it.getIntExtra(BatteryManager.EXTRA_HEALTH, -1)



                  return Stats(level, temperature, voltage, technology, plugged, health)
                }
}

并在 MainActivity 中 onCreate()

 override fun onCreate(savedInstanceState: Bundle?) {
     super.onCreate(savedInstanceState)
     setContentView(R.layout.activity_main)

     val stats = getBatteryInfo()

 }

fun getBatteryInfo(): Stats? {
 var stats: Stats? = null
 val intent: Intent? = IntentFilter(Intent.ACTION_BATTERY_CHANGED).let { ifilter ->
                registerReceiver(null, ifilter)
            }
 intent?.let { batteryIntent ->
                stats = BatteryInfoUtils.getBatteryInfoFromIntent(batteryIntent)
  }
 return stats
}