J'enregistre un écouteur de changement de préférence comme celui-ci (dans le onCreate()
de mon activité principale):
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
prefs.registerOnSharedPreferenceChangeListener(
new SharedPreferences.OnSharedPreferenceChangeListener() {
public void onSharedPreferenceChanged(
SharedPreferences prefs, String key) {
System.out.println(key);
}
});
Le problème est que l'auditeur n'est pas toujours appelé. Cela fonctionne pour les premières fois une préférence est modifiée, puis elle n'est plus appelée jusqu'à ce que je désinstalle et réinstalle l'application. Aucun redémarrage de l'application ne semble le résoudre.
J'ai trouvé un fil de liste de diffusion signalant le même problème, mais personne ne lui a vraiment répondu. Qu'est-ce que je fais mal?
la source
cette réponse acceptée est correcte, car pour moi, elle crée une nouvelle instance chaque reprise de l'activité
alors que diriez-vous de garder la référence à l'auditeur dans l'activité
et dans votre onResume et onPause
cela sera très similaire à ce que vous faites, sauf que nous conservons une référence stricte.
la source
super.onResume()
avantgetPreferenceScreen()...
?super.onResume()
est requis OU l'utiliser AVANTgetPreferenceScreen()
est requis? parce que je parle du bon endroit. cs.dartmouth.edu/~campbell/cs65/lecture05/lecture05.htmlthis
et nonlistener
, cela a provoqué une erreur et j'ai pu résoudre mon problème. Btw ces deux méthodes sont publiques maintenant, non protégéesComme c'est la page la plus détaillée du sujet, je veux ajouter mon 50ct.
J'ai eu le problème que OnSharedPreferenceChangeListener n'a pas été appelé. Mes préférences partagées sont récupérées au début de l'activité principale par:
Mon code PreferenceActivity est court et ne fait rien d'autre que d'afficher les préférences:
Chaque fois que le bouton de menu est enfoncé, je crée la PreferenceActivity à partir de l'activité principale:
Notez que l'enregistrement de OnSharedPreferenceChangeListener doit être effectué APRÈS la création de PreferenceActivity dans ce cas, sinon le gestionnaire de l'activité principale ne sera pas appelé !!! Cela m'a pris un peu de temps pour réaliser que ...
la source
La réponse acceptée crée un appel à
SharedPreferenceChangeListener
chaque foisonResume
. @Samuel le résout en devenantSharedPreferenceListener
membre de la classe Activity. Mais il y a une troisième et une solution plus simple que Google utilise également dans ce codelab . Faites en sorte que votre classe d'activité implémente l'OnSharedPreferenceChangeListener
interface et écraseonSharedPreferenceChanged
l'activité, ce qui rend l'activité elle-même aSharedPreferenceListener
.la source
Code Kotlin pour enregistrer SharedPreferenceChangeListener, il détecte quand le changement se produira sur la clé enregistrée:
vous pouvez mettre ce code dans onStart (), ou ailleurs .. * Considérez que vous devez utiliser
ou vos codes dans le bloc "// Do Something" seront mal exécutés pour chaque changement qui se produira dans n'importe quelle autre clé de sharedPreferences
la source
Donc, je ne sais pas si cela aiderait vraiment quelqu'un, cela a résolu mon problème. Même si j'avais mis en œuvre le
OnSharedPreferenceChangeListener
comme indiqué par la réponse acceptée . Pourtant, j'avais une incohérence avec l'auditeur appelé.Je suis venu ici pour comprendre que l'Android l'envoie juste pour la collecte des déchets après un certain temps. Alors, j'ai regardé mon code. À ma honte, je n'avais pas déclaré l'auditeur GLOBALEMENT mais plutôt à l'intérieur du
onCreateView
. Et c'est parce que j'ai écouté Android Studio me dire de convertir l'auditeur en une variable locale.la source
Il est logique que les écouteurs soient conservés dans WeakHashMap.Parce que la plupart du temps, les développeurs préfèrent écrire le code comme ceci.
Cela peut sembler pas mal. Mais si le conteneur d'OnSharedPreferenceChangeListeners n'était pas WeakHashMap, ce serait très mauvais.Si le code ci-dessus était écrit dans une activité. Puisque vous utilisez une classe interne non statique (anonyme) qui contiendra implicitement la référence de l'instance englobante. Cela entraînera une fuite de mémoire.
De plus, si vous conservez l'écouteur en tant que champ, vous pouvez utiliser registerOnSharedPreferenceChangeListener au début et appeler unregisterOnSharedPreferenceChangeListener à la fin. Mais vous ne pouvez pas accéder à une variable locale dans une méthode hors de sa portée. Vous avez donc juste la possibilité de vous inscrire mais aucune chance de désinscrire l'auditeur. Ainsi, l'utilisation de WeakHashMap résoudra le problème. C'est ainsi que je recommande.
Si vous créez l'instance d'écouteur en tant que champ statique, cela évitera la fuite de mémoire causée par la classe interne non statique. Mais comme les écouteurs peuvent être multiples, cela devrait être lié à l'instance. Cela réduira le coût de la gestion du rappel onSharedPreferenceChanged .
la source
Lors de la lecture de données lisibles par Word partagées par la première application, nous devrions
Remplacer
avec
dans la deuxième application pour obtenir une valeur mise à jour dans la deuxième application.
Mais ça ne marche toujours pas ...
la source