使用localBroadcastManager。在每个呼叫之后更新活动UI的多次广播。

发布于 2025-01-26 22:52:44 字数 1612 浏览 4 评论 0原文

我有一项服务,每次获得位置更新时,都会使用LocalBroadcastManager与活动进行通信。 服务中的回调是:

  @Synchronized private fun requestLocationUpdates() {
    mFusedLocationClient = LocationServices.getFusedLocationProviderClient(this)
    createLocationRequest()
    val locationCallback: LocationCallback?
    locationCallback = object : LocationCallback() {
        override fun onLocationResult(locationResult: LocationResult) {
            synchronized(this) {
                    while (...) {
        
        sendBroadcast(speed, volume)
        sleep(500)
    }
                }
            }
        }
    }
    mFusedLocationClient.requestLocationUpdates(
        mLocationRequest,
        locationCallback,
        Looper.getMainLooper()
    )
}

    private fun sendBroadcast(speed: Double, volume : Int) {
    val intent = Intent(BROADCAST_INTENT)
    intent.putExtra(BROADCAST_SPEED, speed)
    intent.putExtra(BROADCAST_VOLUME, volume)
    mBroadcastManager.sendBroadcast(intent)
}

该活动具有一个命令处理程序:

    private val broadcastReceiver: BroadcastReceiver = object : BroadcastReceiver() {
    override fun onReceive(context: Context?, intent: Intent) {
        handleIntent(intent)
    }
}

private fun handleIntent(intent: Intent) {
    if (intent.action == BROADCAST_INTENT) {
        val speed = intent.getDoubleExtra(BROADCAST_SPEED, 0.0)
        mTextViewSpeed.text = speed
        val volume = intent.getIntExtra(BROADCAST_VOLUME, 0)
        mTextViewVolume.text = volume
    }
}

当要使用应该更新文本视图的断点进行调试时,我会看到更新视图多次运行的呼叫具有不同的值。但是UI仅更新最后一个值。

为什么不立即更新?有什么方法可以修复它?

I have a service which communicates with the activity using LocalBroadcastManager every time it gets a location update.
The callback in the service is:

  @Synchronized private fun requestLocationUpdates() {
    mFusedLocationClient = LocationServices.getFusedLocationProviderClient(this)
    createLocationRequest()
    val locationCallback: LocationCallback?
    locationCallback = object : LocationCallback() {
        override fun onLocationResult(locationResult: LocationResult) {
            synchronized(this) {
                    while (...) {
        
        sendBroadcast(speed, volume)
        sleep(500)
    }
                }
            }
        }
    }
    mFusedLocationClient.requestLocationUpdates(
        mLocationRequest,
        locationCallback,
        Looper.getMainLooper()
    )
}

    private fun sendBroadcast(speed: Double, volume : Int) {
    val intent = Intent(BROADCAST_INTENT)
    intent.putExtra(BROADCAST_SPEED, speed)
    intent.putExtra(BROADCAST_VOLUME, volume)
    mBroadcastManager.sendBroadcast(intent)
}

The activity has an onrecieve handler:

    private val broadcastReceiver: BroadcastReceiver = object : BroadcastReceiver() {
    override fun onReceive(context: Context?, intent: Intent) {
        handleIntent(intent)
    }
}

private fun handleIntent(intent: Intent) {
    if (intent.action == BROADCAST_INTENT) {
        val speed = intent.getDoubleExtra(BROADCAST_SPEED, 0.0)
        mTextViewSpeed.text = speed
        val volume = intent.getIntExtra(BROADCAST_VOLUME, 0)
        mTextViewVolume.text = volume
    }
}

When debugging with a breakpoint where the TextView is supposed to get updated, I see the calls to update the views run multiple times with different values. But the UI only updates with the last value.

Why is it not updated immediately? Any way to fix it?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

池木 2025-02-02 22:52:44

您的问题是时...循环在主(UI)线程上运行。这不仅导致您的问题,而且非常非常糟糕。当此循环运行时,没有UI更新可能会发生,因此您的应用程序将非常缓慢,并且Android可能会使用ANR(应用程序不响应)错误将其杀死。

要解决此问题,请确保您的位置回调在另一个线程上运行。类似的内容:

increate() service 中,创建并启动handlerthread

private val mHandlerThread = HandlerThread("locationUpdates")
mHandlerThread.start()

现在,传递looperhandlerthread的fuse位置客户端的处理:

mFusedLocationClient.requestLocationUpdates(
    mLocationRequest,
    locationCallback,
    mHandlerThread.getLooper()
)

这将确保位置回调在handlerthread上执行,而不是在主(UI)线程上执行。

确保在ondestroy() service>服务> Service 之类的HandlerThread中停止handlerthread

mHandlerThread.quit()

Your problem is that the while... loop is running on the main (UI) Thread. This is not only causing your problem, but is also very very bad. No UI updates can happen while this while... loop is running, so your app will be very sluggish and Android may kill it off with an ANR (Application Not Responding) error.

To fix this, make sure that your location callback gets run on another Thread. Something like this:

In onCreate() of your Service, create and start a HandlerThread:

private val mHandlerThread = HandlerThread("locationUpdates")
mHandlerThread.start()

Now, pass the Looper of that HandlerThread to the fused location client:

mFusedLocationClient.requestLocationUpdates(
    mLocationRequest,
    locationCallback,
    mHandlerThread.getLooper()
)

This will ensure that the location callbacks get executed on the HandlerThread and not on the main (UI) Thread.

Make sure to stop the HandlerThread in onDestroy() of the Service like this:

mHandlerThread.quit()
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文