Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[FEATURE REQUEST] Do not call onSharedPreferenceChanged() for self change #60

Open
teqtic opened this issue Oct 12, 2024 · 5 comments
Open

Comments

@teqtic
Copy link

teqtic commented Oct 12, 2024

I'm in a situation where I do NOT want to be notified of a preference change that was just made from the same activity or service where the SharedPreferencesChangeListener is registered, but I DO want to be notified of changes made by a different class with a different instance of SharedPreferences.Editor(). One way to do this would be to pass a writer identifier tag with any commit call and then pass this to the SharedPreferencesChangeListener so all listeners know who made the change.

If this is already possible please let me know how! As it is now, I could keep track of which preference keys to ignore for the upcoming calls to onSharedPreferenceChanged() but that seems like a bit of an ugly solution, and I'd have to update this list every time I commit. Another way would be to unregister the listener before a commit and re-register right after. Also not ideal if it leads to missed changes from a different process.

P.S. Thank you for this library! I just spent all day migrating over to it. If this is not the place to ask for features, please let me know!

@pablobaxter
Copy link
Owner

At this time, Harmony is meant to just be a re-implementation of SharedPreferences, with minor fixes to the implementation. This would be a move away from the current SharedPreferences interface.

You can use a HashSet to add the keys for each Activity/Receiver/Service on commits/apply, and removing the key on the listener in the SharedPreferencesChangeListener. Keep in mind that the callback of onSharedPreferenceChanged() is done on the main thread, in case you are calling commit()/apply() on multiple threads in the same Activity/Receiver/Service.

@teqtic
Copy link
Author

teqtic commented Oct 12, 2024

Would you please explain how using HashSet can achieve what I want? If I add the information of who made the commit to the key value, wouldn't it be stored with that longer key? Or are you saying I would wait to receive it with the modified key, and then re-commit it without the extra info in the key? Maybe I'm completely missing what you are suggesting.

@teqtic teqtic closed this as completed Oct 12, 2024
@teqtic teqtic reopened this Oct 12, 2024
@pablobaxter
Copy link
Owner

I'm saying that if you make a call to something like sharedPrefs.edit().putBoolean("foobar", true).apply(), you should also add in "foobar" to a hash set, and in the OnPreferenceChangeListener of the same Activity/Service/Receiver, you just call hashSet.remove(key). If it is true, it most likely came from the same class, if it's false, it came from somewhere else.

@teqtic
Copy link
Author

teqtic commented Oct 13, 2024

Ah yes that's basically what I've done. The problem is if two or more writers are writing the same key at the same time, the listener won't know for sure which change notification was theirs and may discard the incorrect change. Am I right in predicting this? It shouldn't matter too much for me as it will still update the local value in memory from sharedPrefs with the second call.

@pablobaxter
Copy link
Owner

Regardless of when the key comes in, when you query the SharedPreferences, it'll give you the latest value stored. For example, if you call prefs.edit().putInt("foo", prefs.getInt("foo", 0) + 1).commit() twice, it's completely possible that by the time you get the events in the change listener, the value would already have incremented by 2. This is because in Harmony, we post the calls to onSharedPreferenceChanged to the end of the main thread (via Handler.post()).

So even if you have some way to notify that your change came from the same Editor, all you'll be notified is that the key changed, not that the value changed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants