我已经实施了 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);

我像其他许多人一样到达这里,因为当我从我的布尔开始时,我的听众不会被解雇 truefalse, , 或相反亦然。

经过大量阅读和重构,切换 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);

在第二个应用程序中以获取第二个应用程序中的更新值。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top