将数据从作为生命周期观察者的类传递到活动



我有一个类BatteryInfo,它是一个生命周期观察者,在这个类中,有一个BroadCastReceiver负责获取所有电池信息。这个类与我调用它的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 方法调用这个类,就像这样

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

我知道这不是你的答案,但这是一种不同的完成工作的方法。它还会删除所有样板代码。

您可以使用对象从意图中提取所有数据并返回数据类的实例。 在此处阅读有关 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
}

我已经在MutableLiveData和LiveData的帮助下完成了这项工作,但我不确定这是一个完美的解决方案还是一个黑客解决方案。我想做一个遵循MVVM干净架构SOLID原则的完美解决方案,而无需创建多个对象,因为它非常昂贵。

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

最新更新