使用localBroadcastManager。在每个呼叫之后更新活动UI的多次广播。
我有一项服务,每次获得位置更新时,都会使用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 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
您的问题是
时...
循环在主(UI)线程上运行。这不仅导致您的问题,而且非常非常糟糕。当此循环运行时,没有UI更新可能会发生,因此您的应用程序将非常缓慢,并且Android可能会使用ANR(应用程序不响应)错误将其杀死。要解决此问题,请确保您的位置回调在另一个线程上运行。类似的内容:
在
increate()
service 中,创建并启动handlerthread
:现在,传递
looper
该handlerthread
的fuse位置客户端的处理:这将确保位置回调在
handlerthread
上执行,而不是在主(UI)线程上执行。确保在
ondestroy()
service>服务> Service 之类的HandlerThread
中停止handlerthread
。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 thiswhile...
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 yourService
, create and start aHandlerThread
:Now, pass the
Looper
of thatHandlerThread
to the fused location client: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
inonDestroy()
of theService
like this: