Kotlin:调用函数从 BroadcastReceiver onReceive 更新 UI
Kotlin: Call a function to update UI from BroadcastReceiver onReceive
我是 Kotlin 的新手,它看起来很棒!虽然今天,我一直在尝试做一些在 Java 中非常简单的事情,但我完全卡住了。
我正在使用广播接收器来确定设备何时连接/断开电源。我需要做的就是相应地更新我的 UI。
我的代码
这是我的 BroadcastReceiver
class,它似乎工作正常。
class PlugInReceiver : BroadcastReceiver() {
override fun onReceive(context: Context, intent: Intent) {
val action = intent.action
if (action == Intent.ACTION_POWER_CONNECTED) {
// Do stuff when power connected
}
else if (action == Intent.ACTION_POWER_DISCONNECTED) {
// Do more stuff when power disconnected
}
}
}
现在在我的 MainActivity
中(但在其他地方,稍后),我想在触发意图时更新我的 UI,例如在下面的函数中,背景颜色发生变化。
private fun updateBackgroundColor( newBgColorId: Int = R.color.colorAccent){
val mainLayout = findViewById<View>(R.id.mainLayout)
val colorFade = ObjectAnimator.ofObject(
mainLayout, "backgroundColor", ArgbEvaluator(), oldBgColor, newBgColor)
colorFade.start()
}
问题
How can I call a function on the MainActivity, or update my UI when the BroadcastReceiver
fires an event?
到目前为止我尝试了什么
我研究了在某处有一个静态变量,存储 BroadcastReciever 的结果,然后在我的 UI class 中观察并相应地调用适当的函数。虽然在谷歌搜索如何做到这一点之后,看起来这在 Kotlin 中并不是一个好的方法。
考虑尝试 运行 UI 线程上的 BroadcastReciever,但这听起来是个糟糕的主意。
尝试将 Java 实现与我的 Kotlin class 混合使用,但无法正常工作。
令人沮丧的是,我在 SO 上发现了几个非常相似的问题。然而,他们的实现似乎都使用了 Java 特定的功能:
- Android BroadcastReceiver onReceive Update TextView in MainActivity
- How to update UI in a BroadcastReceiver
- Calling a Activity method from BroadcastReceiver in Android
我敢肯定这对大多数 Android 开发人员来说是一个微不足道的问题,但我迷路了!如果您需要更多详细信息,请告诉我。非常感谢!
onReceive(...) 方法在主线程上运行。您可以在 onStart() 中注册您的 Activity 并在 onStop() 中注销它,这将保证您的 UI 在收到事件时存在。
共享信息以在 Kotlin 中注册 BroadcastReceiver
第 1 步。在 MainActivity.kt
中创建 BroadcastReceiver
private val mPlugInReceiver = object : BroadcastReceiver() {
override fun onReceive(context: Context?, intent: Intent?) {
when (intent?.action) {
Intent.ACTION_POWER_CONNECTED -> {
//update your main background color
updateBackgroundColor()
}
Intent.ACTION_POWER_DISCONNECTED -> {
//update your main background color
updateBackgroundColor()
}
}
}
}
步骤 2. 创建 IntentFilter
private fun getIntentFilter(): IntentFilter {
val iFilter = IntentFilter()
iFilter.addAction(Intent.ACTION_POWER_CONNECTED)
iFilter.addAction(Intent.ACTION_POWER_DISCONNECTED)
return iFilter
}
步骤 3. 在 onStart() 注册接收器
override fun onStart() {
super.onStart()
registerReceiver(mPlugInReceiver, getIntentFilter())
}
第 4 步。在 onStop() 取消注册接收器
override fun onStop() {
super.onStop()
unregisterReceiver(mPlugInReceiver)
}
如果您有自定义 BroadcastReceiver,您可以使用 LocalBroadcastManager
注册并创建您的本地 IntentFilter
private val mLocalBroadcastReceiver = object : BroadcastReceiver() {
override fun onReceive(context: Context?, intent: Intent?) {
when (intent?.action) {
AnyService.UPDATE_ANY -> {
}
}
}
}
private fun getLocalIntentFilter(): IntentFilter {
val iFilter = IntentFilter()
iFilter.addAction(AnyService.UPDATE_ANY)
return iFilter
}
注册本地接收器
LocalBroadcastManager.getInstance(applicationContext).registerReceiver(mLocalBroadcastReceiver, getLocalIntentFilter())
注销本地接收器LocalBroadcastManager.getInstance(applicationContext).unregisterReceiver(mLocalBroadcastReceiver)
最好的实现方法是在 BroadcastReceiver 中创建一个抽象方法,当调用 onReceive() 方法时,您可以调用将由您的 activity 实现的方法。
BroadcastReceiver 示例:
abstract class ConnectionBroadcastReceiver : BroadcastReceiver() {
override fun onReceive(context: Context, intent: Intent) {
//Do the checks or whatever you want
var isConnected = true
broadcastResult(isConnected)
}
protected abstract fun broadcastResult(connected: Boolean)
}
以及您 activity 中的代码(例如在 onCreate 或 onStart 中)。在这里您使用方法实现注册广播接收器,在这里您可以更新 UI:
var connectionBroadcastReceiver = object : ConnectionBroadcastReceiver() {
override fun broadcastResult(connected: Boolean) {
if(isConnected){
refreshList()
}
}
}
val intentFilter = IntentFilter()
intentFilter.addAction(ConnectivityManager.CONNECTIVITY_ACTION)
this.registerReceiver(connectionBroadcastReceiver, intentFilter)
不要忘记在 (onPause||onStop||onDestroy) 中注销接收器,但这不是绝对必要的。
我是 Kotlin 的新手,它看起来很棒!虽然今天,我一直在尝试做一些在 Java 中非常简单的事情,但我完全卡住了。
我正在使用广播接收器来确定设备何时连接/断开电源。我需要做的就是相应地更新我的 UI。
我的代码
这是我的 BroadcastReceiver
class,它似乎工作正常。
class PlugInReceiver : BroadcastReceiver() {
override fun onReceive(context: Context, intent: Intent) {
val action = intent.action
if (action == Intent.ACTION_POWER_CONNECTED) {
// Do stuff when power connected
}
else if (action == Intent.ACTION_POWER_DISCONNECTED) {
// Do more stuff when power disconnected
}
}
}
现在在我的 MainActivity
中(但在其他地方,稍后),我想在触发意图时更新我的 UI,例如在下面的函数中,背景颜色发生变化。
private fun updateBackgroundColor( newBgColorId: Int = R.color.colorAccent){
val mainLayout = findViewById<View>(R.id.mainLayout)
val colorFade = ObjectAnimator.ofObject(
mainLayout, "backgroundColor", ArgbEvaluator(), oldBgColor, newBgColor)
colorFade.start()
}
问题
How can I call a function on the MainActivity, or update my UI when the
BroadcastReceiver
fires an event?
到目前为止我尝试了什么
我研究了在某处有一个静态变量,存储 BroadcastReciever 的结果,然后在我的 UI class 中观察并相应地调用适当的函数。虽然在谷歌搜索如何做到这一点之后,看起来这在 Kotlin 中并不是一个好的方法。
考虑尝试 运行 UI 线程上的 BroadcastReciever,但这听起来是个糟糕的主意。
尝试将 Java 实现与我的 Kotlin class 混合使用,但无法正常工作。
令人沮丧的是,我在 SO 上发现了几个非常相似的问题。然而,他们的实现似乎都使用了 Java 特定的功能:
- Android BroadcastReceiver onReceive Update TextView in MainActivity
- How to update UI in a BroadcastReceiver
- Calling a Activity method from BroadcastReceiver in Android
我敢肯定这对大多数 Android 开发人员来说是一个微不足道的问题,但我迷路了!如果您需要更多详细信息,请告诉我。非常感谢!
onReceive(...) 方法在主线程上运行。您可以在 onStart() 中注册您的 Activity 并在 onStop() 中注销它,这将保证您的 UI 在收到事件时存在。
共享信息以在 Kotlin 中注册 BroadcastReceiver
第 1 步。在 MainActivity.kt
中创建 BroadcastReceiverprivate val mPlugInReceiver = object : BroadcastReceiver() {
override fun onReceive(context: Context?, intent: Intent?) {
when (intent?.action) {
Intent.ACTION_POWER_CONNECTED -> {
//update your main background color
updateBackgroundColor()
}
Intent.ACTION_POWER_DISCONNECTED -> {
//update your main background color
updateBackgroundColor()
}
}
}
}
步骤 2. 创建 IntentFilter
private fun getIntentFilter(): IntentFilter {
val iFilter = IntentFilter()
iFilter.addAction(Intent.ACTION_POWER_CONNECTED)
iFilter.addAction(Intent.ACTION_POWER_DISCONNECTED)
return iFilter
}
步骤 3. 在 onStart() 注册接收器
override fun onStart() {
super.onStart()
registerReceiver(mPlugInReceiver, getIntentFilter())
}
第 4 步。在 onStop() 取消注册接收器
override fun onStop() {
super.onStop()
unregisterReceiver(mPlugInReceiver)
}
如果您有自定义 BroadcastReceiver,您可以使用 LocalBroadcastManager
注册并创建您的本地 IntentFilter
private val mLocalBroadcastReceiver = object : BroadcastReceiver() {
override fun onReceive(context: Context?, intent: Intent?) {
when (intent?.action) {
AnyService.UPDATE_ANY -> {
}
}
}
}
private fun getLocalIntentFilter(): IntentFilter {
val iFilter = IntentFilter()
iFilter.addAction(AnyService.UPDATE_ANY)
return iFilter
}
注册本地接收器
LocalBroadcastManager.getInstance(applicationContext).registerReceiver(mLocalBroadcastReceiver, getLocalIntentFilter())
注销本地接收器LocalBroadcastManager.getInstance(applicationContext).unregisterReceiver(mLocalBroadcastReceiver)
最好的实现方法是在 BroadcastReceiver 中创建一个抽象方法,当调用 onReceive() 方法时,您可以调用将由您的 activity 实现的方法。
BroadcastReceiver 示例:
abstract class ConnectionBroadcastReceiver : BroadcastReceiver() {
override fun onReceive(context: Context, intent: Intent) {
//Do the checks or whatever you want
var isConnected = true
broadcastResult(isConnected)
}
protected abstract fun broadcastResult(connected: Boolean)
}
以及您 activity 中的代码(例如在 onCreate 或 onStart 中)。在这里您使用方法实现注册广播接收器,在这里您可以更新 UI:
var connectionBroadcastReceiver = object : ConnectionBroadcastReceiver() {
override fun broadcastResult(connected: Boolean) {
if(isConnected){
refreshList()
}
}
}
val intentFilter = IntentFilter()
intentFilter.addAction(ConnectivityManager.CONNECTIVITY_ACTION)
this.registerReceiver(connectionBroadcastReceiver, intentFilter)
不要忘记在 (onPause||onStop||onDestroy) 中注销接收器,但这不是绝对必要的。