TL; DR
我需要更新片段的UI(toggleButton),当它在正在运行的服务的屏幕上可见时。
背景
我在Fragment上有一个toggleButton
(名为homeFragment)。它显示停止文本if(toggleButton.isChecked)
,否则显示开始文本。
此toggleButton
启动和停止服务。
现在,有两种方法可以停止此服务。一种是再次点击toggleButton
(停止服务),另一种是通过服务本身。
启动此服务后,toggleButton
会显示“停止”文字。
此服务会创建粘滞通知并在此之后调用this.stopSelf
。
此通知有一个按钮关闭此通知。
此选项会调用BroadcastReceiver
来停止/取消通知。
问题/需求
现在,当通过通知按钮关闭服务时,如果app可见或位于前台,我想在Fragment上触发toggleButton
以再次显示 Start 文本。
如果appActivity处于后台/暂停/关闭状态,我不需要处理此问题(我通过检查sharedPrefs
中的onCreate()
来处理此问题)
我试过了:
使用布尔值SharedPref键(比如isServiceRunning
)来跟踪服务状态。在onCreate()
中,我保存了true
布尔值。在onDestoy()
中,我保存了false
布尔值。
然后,我将onSharedPreferencesChangeListener
注册到sharedPrefs(inside fragment)
,检查isServiceRunning
的sharedPrefkey是否已更改。
如果是,则调用toggleButton.setChecked(false);
此方法很少有效。有时它有效,有时没有任何反应。
使用LocalBroadcastReceiver
,但它有很多错误。就像,can't Instantiate Receiver: no empty method
。我试着解决,
但想通了,需要做很多工作。此外,访问另一个类中的Fragment视图只是一团糟,因为你必须给它们片段layout
任何时候都可以null
。从View
给这个接收器类提供onViewCreated()
元素很困难。我尝试过layout
+ findViewById
这样做,
但没有成功/错误。
这种方法从未奏效,我认为效率不高。
到处使用static
个变量。所以,我创建了一个全局View
元素(比如说activeLayout
)。
它是private
和static
,因此static
方法(切换toggleButton
的状态)可以访问片段的布局。
从activeLayout
方法为onViewCreated()
分配了一个布局。
现在,如果我从我的static
调用此stopNotificationReceiver
方法,它可以正常工作(我只检查了两次)。但是,显示了一个新的警告:
警告:不要将Android上下文类放在静态字段中;这是一个内存泄漏(也打破了Instant Run)
所以,我不能将activeLayout
作为static
变量,这打破了这个想法。
如果我做错了,请建议我另类。或者纠正我如何做到这一点。
答案 0 :(得分:3)
使用广播接收器并在片段中注册
您可以使用ur service
中的以下代码来调用Broadcast reciverIntent intent = new Intent();
intent.putExtra("extra", cappello);
intent.setAction("com.my.app");
sendBroadcast(intent);
在Fragment中实现BroadcastReceiver:
private class MyBroadcastReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
Bundle extras = intent.getExtras();
String state = extras.getString("extra");
updateView(state);// update your textView in the main layout
}
}
并将其注册在Fragment的onResume()中:
IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction("com.my.app");
receiver = new MyBroadcastReceiver();
registerReceiver(receiver, intentFilter);