如果在单独的活动中发生变化,则没有解雇OnsharedPreferencechange。
-
05-10-2019 - |
题
我已经实施了 onSharedPreferenceChanged
在我的主要活动中。
如果我更改主要活动中的偏好,我的活动会开火。
如果我通过我的首选项屏幕更改首选项(PreferenceActivity
)当更改偏好时,我的事件不会发射(因为这是一项单独的活动,并且对共享流程单独引用?)
是否有人建议我应该如何克服这种情况?
谢谢!
EDIT1:我尝试在我的首选项活动中添加活动处理程序,但它永远不会发射。在我的偏好活动中征用以下方法。当我更改值时,它永远不会打印消息(msg()
是包装纸 Log.d
).
private void registerChangeListener () {
SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(this);
sp.registerOnSharedPreferenceChangeListener(new OnSharedPreferenceChangeListener () {
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
msg (" ***** Shared Preference Update ***** ");
Intent i = new Intent();
i.putExtra("KEY", key);
i.setAction("com.gtosoft.dash.settingschanged");
sendBroadcast(i);
// TODO: fire off the event
}
});
}
解决方案
这 OnSharedPreferenceChangeListener
如果您使用匿名类,请在情况下收集垃圾。
解决该问题,请使用以下代码 PreferenceActivity
注册并解开“更改”听众:
public class MyActivity extends PreferenceActivity implements
OnSharedPreferenceChangeListener {
@Override
protected void onResume() {
super.onResume();
// Set up a listener whenever a key changes
getPreferenceScreen().getSharedPreferences()
.registerOnSharedPreferenceChangeListener(this);
}
@Override
protected void onPause() {
super.onPause();
// Unregister the listener whenever a key changes
getPreferenceScreen().getSharedPreferences()
.unregisterOnSharedPreferenceChangeListener(this);
}
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences,String key)
{
// do stuff
}
此外,请注意,仅当实际值更改时,听众才会被调用。再次设置相同的值不会发射听众。
也可以看看 sharedPreferences.onsharedPreferencechangelistener不被始终称为
其他提示
发生这种情况是因为垃圾收集器。它的作品只有一次。然后将引用收集为垃圾。因此,为侦听器创建实例字段。
private OnSharedPreferenceChangeListener listner;
listner = new SharedPreferences.OnSharedPreferenceChangeListener() {
@Override
public void onSharedPreferenceChanged(SharedPreferences prefs, String key) {
//implementation goes here
}
};
prefs.registerOnSharedPreferenceChangeListener(listner);
我像其他许多人一样到达这里,因为当我从我的布尔开始时,我的听众不会被解雇 true
至 false
, , 或相反亦然。
经过大量阅读和重构,切换 contexts/inner
classes/privates/static/
之类的,我意识到我的(愚蠢)错误:
这 onSharedPreferenceChanged
是 只要 如果某件事发生了变化。仅有的。曾经。
在我的测试中,我一直很愚蠢,一直单击相同的按钮,因此一直为优先考虑分配相同的布尔值,因此它永远不会改变。
希望这对某人有帮助!
避免问题的另一种方法是使您的活动成为听众类。由于只有一个具有独特名称的替代方法,您可以做到这一点:
public class MainActivity extends AppCompatActivity implements SharedPreferences.OnSharedPreferenceChangeListener
{
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
sharedPreferences.registerOnSharedPreferenceChangeListener(this);
...
}
@Override
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key)
{
...
}
}
请注意,原始问题说明了聆听偏好性的设置变化的主动性。然后,Asker添加了一个“ Edit1”,并将问题更改为在偏好性本身中聆听。这比前者容易,似乎是所有答案所假设的。但是,如果您仍然想要以前的情况怎么办?
好吧,它也可以正常工作,但是不要使用onResume()和onpause()注册和注册听众。这样做会导致听众无效,因为用户使用偏好性(当您考虑时,这是有道理的)。因此,它将起作用,但是即使用户不使用它,您的主动脉仍将在后台聆听。有点浪费资源,不是吗?因此,还有另一种解决方案似乎可以起作用,只需将方法添加到onResume()中即可重新阅读所有偏好。这样,当用户以偏好性完成编辑偏好时,当用户返回到它时,主动脉将使它们接听,并且您 根本不需要听众.
有人请让我知道他们是否看到这种方法的问题。
你为什么不添加一个 onSharedPreferenceChanged
在其余的活动中,偏好可能会改变?
垃圾收集器擦除...您应该考虑使用应用程序上下文...或在应用程序启动时添加代码...然后在应用程序上下文中添加侦听器...
考虑保持 首选项 在Android内部 应用程序 类实例。尽管它不是一个干净的解决方案存储在应用程序内部的存储参考,应该阻止GC收集侦听器,并且您仍然应该能够接收DB更改更新。记住那个偏好经理 才不是 存储对听众的强烈参考! ((虚弱的船)
/**
* Main application class
*/
class MyApp : Application(), KoinComponent {
var preferenceManager: SharedPreferences? = null
var prefChangeListener: MySharedPrefChangeListener? = null
override fun onCreate() {
super.onCreate()
preferenceManager = PreferenceManager.getDefaultSharedPreferences(this)
prefChangeListener = MySharedPrefChangeListener()
preferenceManager?.registerOnSharedPreferenceChangeListener(prefChangeListener)
}
}
和
class MySharedPrefChangeListener : SharedPreferences.OnSharedPreferenceChangeListener {
/**
* Called when a shared preference is changed, added, or removed.
*/
override fun onSharedPreferenceChanged(sharedPreferences: SharedPreferences?, key: String?) {
if (sharedPreferences == null)
return
if (sharedPreferences.contains(key)) {
// action to perform
}
}
}
在阅读第一个应用程序共享的单词可读数据时,我们应该
代替
getSharedPreferences("PREF_NAME", Context.MODE_PRIVATE);
和
getSharedPreferences("PREF_NAME", Context.MODE_MULTI_PROCESS);
在第二个应用程序中以获取第二个应用程序中的更新值。