From 5ca37f36fd5a181058ad56b3be1536f1d2e23c1f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mathieu=20M=C3=A9a?= Date: Thu, 23 Apr 2026 16:09:44 -0400 Subject: [PATCH 1/9] Fix ThreadConstraint for AGP `9.2.0` - https://github.com/mtransitapps/commons/pull/702 --- .../android/commons/PreferenceUtils.java | 128 ++---------------- .../mtransit/android/commons/TaskUtils.java | 11 +- 2 files changed, 16 insertions(+), 123 deletions(-) diff --git a/src/main/java/org/mtransit/android/commons/PreferenceUtils.java b/src/main/java/org/mtransit/android/commons/PreferenceUtils.java index f61592f8..35e45a98 100644 --- a/src/main/java/org/mtransit/android/commons/PreferenceUtils.java +++ b/src/main/java/org/mtransit/android/commons/PreferenceUtils.java @@ -4,7 +4,7 @@ import android.content.SharedPreferences; import android.preference.PreferenceManager; -import androidx.annotation.MainThread; +import androidx.annotation.AnyThread; import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.annotation.WorkerThread; @@ -135,6 +135,7 @@ public static String getPREFS_AGENCY_POIS_SHOWING_LIST_INSTEAD_OF_MAP(@NonNull S public static final boolean PREFS_KEEP_MODULE_APP_LAUNCHER_ICON_DEFAULT = true; public static final String PREFS_KEEP_MODULE_APP_LAUNCHER_ICON = "pKeepModuleAppLauncherIcon"; + @SuppressWarnings("deprecation") @WorkerThread @NonNull public static SharedPreferences getPrefDefault(@NonNull Context context) { @@ -278,19 +279,7 @@ private static String getPref(SharedPreferences sharedPreferences, String prefKe return sharedPreferences.getString(prefKey, defaultValue); } - @Deprecated // Thread? - public static void savePrefDefault(@Nullable final Context context, @NonNull final String prefKey, final int newValue, final boolean sync) { - if (context == null) { - return; - } - if (sync) { - savePref(getPrefDefault(context), prefKey, newValue); - return; - } - savePrefDefaultAsync(context, prefKey, newValue); - } - - @MainThread + @AnyThread public static void savePrefDefaultAsync(@NonNull Context context, @NonNull String prefKey, int newValue) { new MTAsyncTask() { @NonNull @@ -307,19 +296,7 @@ protected Void doInBackgroundMT(Void... params) { }.executeOnExecutor(TaskUtils.THREAD_POOL_EXECUTOR); } - @Deprecated // Thread? - public static void savePrefDefault(@Nullable final Context context, @NonNull final String prefKey, final long newValue, final boolean sync) { - if (context == null) { - return; - } - if (sync) { - savePref(getPrefDefault(context), prefKey, newValue); - return; - } - savePrefDefaultAsync(context, prefKey, newValue); - } - - @MainThread + @AnyThread public static void savePrefDefaultAsync(@NonNull Context context, @NonNull String prefKey, long newValue) { new MTAsyncTask() { @NonNull @@ -336,19 +313,7 @@ protected Void doInBackgroundMT(Void... params) { }.executeOnExecutor(TaskUtils.THREAD_POOL_EXECUTOR); } - @Deprecated // Thread? - public static void savePrefDefault(@Nullable final Context context, @NonNull final String prefKey, @Nullable final Boolean newValue, final boolean sync) { - if (context == null) { - return; - } - if (sync) { - savePref(getPrefDefault(context), prefKey, newValue); - return; - } - savePrefDefaultAsync(context, prefKey, newValue); - } - - @MainThread + @AnyThread public static void savePrefDefaultAsync(@NonNull Context context, @NonNull String prefKey, @Nullable Boolean newValue) { new MTAsyncTask() { @NonNull @@ -365,19 +330,7 @@ protected Void doInBackgroundMT(Void... params) { }.executeOnExecutor(TaskUtils.THREAD_POOL_EXECUTOR); } - @Deprecated // Thread? - public static void savePrefDefault(@Nullable final Context context, @NonNull final String prefKey, @Nullable final String newValue, final boolean sync) { - if (context == null) { - return; - } - if (sync) { - savePref(getPrefDefault(context), prefKey, newValue); - return; - } - savePrefDefaultAsync(context, prefKey, newValue); - } - - @MainThread + @AnyThread public static void savePrefDefaultAsync(@NonNull Context context, @NonNull String prefKey, @Nullable String newValue) { new MTAsyncTask() { @NonNull @@ -394,18 +347,6 @@ protected Void doInBackgroundMT(Void... params) { }.executeOnExecutor(TaskUtils.THREAD_POOL_EXECUTOR); } - @Deprecated // Thread? - public static void savePrefLcl(@Nullable final Context context, @NonNull final String prefKey, @Nullable final Integer newValue, final boolean sync) { - if (context == null) { - return; - } - if (sync) { - savePref(getPrefLcl(context), prefKey, newValue); - return; - } - savePrefLclAsync(context, prefKey, newValue); - } - @WorkerThread public static void savePrefLclSync(@Nullable final Context context, @NonNull final String prefKey, @Nullable final Integer newValue) { if (context == null) { @@ -414,7 +355,7 @@ public static void savePrefLclSync(@Nullable final Context context, @NonNull fin savePref(getPrefLcl(context), prefKey, newValue); } - @MainThread + @AnyThread public static void savePrefLclAsync(@NonNull Context context, @NonNull String prefKey, @Nullable Integer newValue) { new MTAsyncTask() { @NonNull @@ -431,18 +372,6 @@ protected Void doInBackgroundMT(Void... params) { }.executeOnExecutor(TaskUtils.THREAD_POOL_EXECUTOR); } - @Deprecated // Thread? - public static void savePrefLcl(@Nullable final Context context, @NonNull final String prefKey, @Nullable final Boolean newValue, final boolean sync) { - if (context == null) { - return; - } - if (sync) { - savePref(getPrefLcl(context), prefKey, newValue); - return; - } - savePrefLclAsync(context, prefKey, newValue); - } - @WorkerThread public static void savePrefLclSync(@Nullable final Context context, @NonNull final String prefKey, @Nullable final Boolean newValue) { if (context == null) { @@ -451,7 +380,7 @@ public static void savePrefLclSync(@Nullable final Context context, @NonNull fin savePref(getPrefLcl(context), prefKey, newValue); } - @MainThread + @AnyThread public static void savePrefLclAsync(@NonNull Context context, @NonNull String prefKey, @Nullable Boolean newValue) { new MTAsyncTask() { @NonNull @@ -468,18 +397,6 @@ protected Void doInBackgroundMT(Void... params) { }.executeOnExecutor(TaskUtils.THREAD_POOL_EXECUTOR); } - @Deprecated // Thread? - public static void savePrefLcl(@Nullable final Context context, @NonNull final String prefKey, @Nullable final Long newValue, final boolean sync) { - if (context == null) { - return; - } - if (sync) { - savePref(getPrefLcl(context), prefKey, newValue); - return; - } - savePrefLclAsync(context, prefKey, newValue); - } - @WorkerThread public static void savePrefLclSync(@Nullable final Context context, @NonNull final String prefKey, @Nullable final Long newValue) { if (context == null) { @@ -488,7 +405,7 @@ public static void savePrefLclSync(@Nullable final Context context, @NonNull fin savePref(getPrefLcl(context), prefKey, newValue); } - @MainThread + @AnyThread public static void savePrefLclAsync(@NonNull Context context, @NonNull String prefKey, @Nullable Long newValue) { new MTAsyncTask() { @NonNull @@ -505,18 +422,6 @@ protected Void doInBackgroundMT(Void... params) { }.executeOnExecutor(TaskUtils.THREAD_POOL_EXECUTOR); } - @Deprecated // Thread? - public static void savePrefLcl(@Nullable final Context context, @NonNull final String prefKey, @Nullable final String newValue, final boolean sync) { - if (context == null) { - return; - } - if (sync) { - savePref(getPrefLcl(context), prefKey, newValue); - return; - } - savePrefLclAsync(context, prefKey, newValue); - } - @WorkerThread public static void savePrefLclSync(@Nullable final Context context, @NonNull final String prefKey, @Nullable final String newValue) { if (context == null) { @@ -525,7 +430,7 @@ public static void savePrefLclSync(@Nullable final Context context, @NonNull fin savePref(getPrefLcl(context), prefKey, newValue); } - @MainThread + @AnyThread public static void savePrefLclAsync(@NonNull Context context, @NonNull String prefKey, @Nullable String newValue) { new MTAsyncTask() { @NonNull @@ -542,17 +447,6 @@ protected Void doInBackgroundMT(Void... params) { }.executeOnExecutor(TaskUtils.THREAD_POOL_EXECUTOR); } - @Deprecated // Thread? - public static void savePrefLcl(@Nullable final Context context, @NonNull final String prefKey, @Nullable final Set newValue, final boolean sync) { - if (context == null) { - return; - } - if (sync) { - savePref(getPrefLcl(context), prefKey, newValue); - return; - } - savePrefLclAsync(context, prefKey, newValue); - } @WorkerThread public static void savePrefLclSync(@Nullable final Context context, @NonNull final String prefKey, @Nullable final Set newValue) { @@ -562,7 +456,7 @@ public static void savePrefLclSync(@Nullable final Context context, @NonNull fin savePref(getPrefLcl(context), prefKey, newValue); } - @MainThread + @AnyThread public static void savePrefLclAsync(@NonNull Context context, @NonNull String prefKey, @Nullable Set newValue) { new MTAsyncTask() { @NonNull diff --git a/src/main/java/org/mtransit/android/commons/TaskUtils.java b/src/main/java/org/mtransit/android/commons/TaskUtils.java index 4e7e437b..871040f4 100644 --- a/src/main/java/org/mtransit/android/commons/TaskUtils.java +++ b/src/main/java/org/mtransit/android/commons/TaskUtils.java @@ -1,5 +1,6 @@ package org.mtransit.android.commons; +import androidx.annotation.AnyThread; import androidx.annotation.NonNull; import androidx.annotation.Nullable; @@ -7,6 +8,7 @@ import java.util.concurrent.Executor; +@SuppressWarnings("deprecation") public final class TaskUtils implements MTLog.Loggable { private static final String LOG_TAG = TaskUtils.class.getSimpleName(); @@ -21,18 +23,15 @@ public String getLogTag() { public static final Executor THREAD_POOL_EXECUTOR = MTAsyncTask.THREAD_POOL_EXECUTOR; @SuppressWarnings("unchecked") + @AnyThread public static void execute(@Nullable MTAsyncTask asyncTask, Params... params) { - if (asyncTask == null) { - return; - } + if (asyncTask == null) return; asyncTask.executeOnExecutor(THREAD_POOL_EXECUTOR, params); } public static boolean cancelQuietly(@Nullable MTAsyncTask asyncTask, boolean mayInterruptIfRunning) { try { - if (asyncTask == null) { - return false; - } + if (asyncTask == null) return false; return asyncTask.cancel(mayInterruptIfRunning); } catch (Exception e) { MTLog.w(LOG_TAG, e, "Error while cancelling task!"); From 8ffb2efd901e12011d026643369c7beb9242db07 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mathieu=20M=C3=A9a?= Date: Mon, 27 Apr 2026 10:49:16 -0400 Subject: [PATCH 2/9] Remove unused --- .../mtransit/android/commons/LiveDataExt.kt | 22 ------------------- 1 file changed, 22 deletions(-) delete mode 100644 src/main/java/org/mtransit/android/commons/LiveDataExt.kt diff --git a/src/main/java/org/mtransit/android/commons/LiveDataExt.kt b/src/main/java/org/mtransit/android/commons/LiveDataExt.kt deleted file mode 100644 index 367255aa..00000000 --- a/src/main/java/org/mtransit/android/commons/LiveDataExt.kt +++ /dev/null @@ -1,22 +0,0 @@ -@file:Suppress("unused") - -package org.mtransit.android.commons - -import androidx.lifecycle.LifecycleOwner -import androidx.lifecycle.LiveData -import androidx.lifecycle.Observer - -fun LiveData.observeNonNull(owner: LifecycleOwner, observer: (t: T) -> Unit) { - this.observe(owner) { - it?.let(observer) - } -} - -fun LiveData.observeOnce(lifecycleOwner: LifecycleOwner, block: (T) -> Unit) { - observe(lifecycleOwner, object : Observer { - override fun onChanged(value: T) { - block(value) - removeObserver(this) - } - }) -} From 4552c3981a0a92ebf81f37de4640c9e81b915fc7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mathieu=20M=C3=A9a?= Date: Wed, 29 Apr 2026 14:44:26 -0400 Subject: [PATCH 3/9] Add `PreferenceChangeLiveData`... --- .../commons/pref/PreferenceChangeLiveData.kt | 27 ++++++++++ .../commons/pref/PreferenceListener.kt | 43 ++++++++++++++++ .../commons/pref/PreferenceLiveData.kt | 50 ++++--------------- .../android/commons/pref/PreferencesExt.kt | 14 +++--- 4 files changed, 87 insertions(+), 47 deletions(-) create mode 100644 src/main/java/org/mtransit/android/commons/pref/PreferenceChangeLiveData.kt create mode 100644 src/main/java/org/mtransit/android/commons/pref/PreferenceListener.kt diff --git a/src/main/java/org/mtransit/android/commons/pref/PreferenceChangeLiveData.kt b/src/main/java/org/mtransit/android/commons/pref/PreferenceChangeLiveData.kt new file mode 100644 index 00000000..0c67702f --- /dev/null +++ b/src/main/java/org/mtransit/android/commons/pref/PreferenceChangeLiveData.kt @@ -0,0 +1,27 @@ +package org.mtransit.android.commons.pref + +import android.content.SharedPreferences +import androidx.lifecycle.LiveData + +class PreferenceChangeLiveData( + private val preferences: SharedPreferences, +) : LiveData() { + + private val listener: SharedPreferences.OnSharedPreferenceChangeListener by lazy { + SharedPreferences.OnSharedPreferenceChangeListener { _, key -> + value = key + } + } + + override fun onActive() { + super.onActive() + preferences.registerOnSharedPreferenceChangeListener(listener) + } + + override fun onInactive() { + super.onInactive() + preferences.unregisterOnSharedPreferenceChangeListener(listener) + } +} + +fun SharedPreferences.preferenceChangeLiveData(): LiveData = PreferenceChangeLiveData(this) diff --git a/src/main/java/org/mtransit/android/commons/pref/PreferenceListener.kt b/src/main/java/org/mtransit/android/commons/pref/PreferenceListener.kt new file mode 100644 index 00000000..281a67fc --- /dev/null +++ b/src/main/java/org/mtransit/android/commons/pref/PreferenceListener.kt @@ -0,0 +1,43 @@ +package org.mtransit.android.commons.pref + +import android.content.SharedPreferences + +class PreferenceListener( + private val preferences: SharedPreferences, + notifyInitValue: Boolean, + private val valueKey: String, + private val getPreferencesValue: () -> T, + private val setValue: (T) -> Unit, + private val getValue: () -> T, +) : SharedPreferences.OnSharedPreferenceChangeListener { + private var needCheckWhenRegister = false + + init { + if (notifyInitValue) { + setValue(getPreferencesValue()) + } + } + + fun register() { + preferences.registerOnSharedPreferenceChangeListener(this) + if (needCheckWhenRegister) { + needCheckWhenRegister = false + updateValue(getPreferencesValue()) + } + } + + fun unregister() { + preferences.unregisterOnSharedPreferenceChangeListener(this) + needCheckWhenRegister = true + } + + override fun onSharedPreferenceChanged(sharedPreferences: SharedPreferences?, key: String?) { + if (key != valueKey) return + updateValue(getPreferencesValue()) + } + + private fun updateValue(newValue: T) { + if (getValue() == newValue) return + setValue(newValue) + } +} diff --git a/src/main/java/org/mtransit/android/commons/pref/PreferenceLiveData.kt b/src/main/java/org/mtransit/android/commons/pref/PreferenceLiveData.kt index 5a58a095..cb91458f 100644 --- a/src/main/java/org/mtransit/android/commons/pref/PreferenceLiveData.kt +++ b/src/main/java/org/mtransit/android/commons/pref/PreferenceLiveData.kt @@ -10,7 +10,16 @@ abstract class PreferenceLiveData( private val notifyInitValue: Boolean ) : LiveData() { - private val listener = PreferenceListener() + private val listener by lazy { + PreferenceListener( + preferences, + notifyInitValue, + key, + ::getPreferencesValue, + ::setValue, + ::getValue + ) + } override fun onActive() { super.onActive() @@ -24,41 +33,4 @@ abstract class PreferenceLiveData( abstract fun getPreferencesValue(): T - inner class PreferenceListener : SharedPreferences.OnSharedPreferenceChangeListener { - private var needCheckWhenRegister = false - - init { - if (notifyInitValue) { - value = getPreferencesValue() - } - } - - fun register() { - preferences.registerOnSharedPreferenceChangeListener(listener) - if (needCheckWhenRegister) { - needCheckWhenRegister = false - updateValue(getPreferencesValue()) - } - } - - fun unregister() { - preferences.unregisterOnSharedPreferenceChangeListener(listener) - needCheckWhenRegister = true - } - - override fun onSharedPreferenceChanged( - sharedPreferences: SharedPreferences?, - key: String? - ) { - if (key == this@PreferenceLiveData.key) { - updateValue(getPreferencesValue()) - } - } - - private fun updateValue(newValue: T) { - if (value != newValue) { - value = newValue - } - } - } -} \ No newline at end of file +} diff --git a/src/main/java/org/mtransit/android/commons/pref/PreferencesExt.kt b/src/main/java/org/mtransit/android/commons/pref/PreferencesExt.kt index dc3787f8..24de81c4 100644 --- a/src/main/java/org/mtransit/android/commons/pref/PreferencesExt.kt +++ b/src/main/java/org/mtransit/android/commons/pref/PreferencesExt.kt @@ -25,16 +25,14 @@ inline fun SharedPreferences.liveDataN( key: String, defaultValue: T? = null, notifyInitValue: Boolean = true, -): LiveData = - object : PreferenceLiveData(this, key, notifyInitValue) { - override fun getPreferencesValue(): T? = get(key, defaultValue) - } +): LiveData = object : PreferenceLiveData(this, key, notifyInitValue) { + override fun getPreferencesValue(): T? = get(key, defaultValue) +} inline fun SharedPreferences.liveData( key: String, defaultValue: T, notifyInitValue: Boolean = true, -): LiveData = - object : PreferenceLiveData(this, key, notifyInitValue) { - override fun getPreferencesValue(): T = get(key, defaultValue) ?: defaultValue - } \ No newline at end of file +): LiveData = object : PreferenceLiveData(this, key, notifyInitValue) { + override fun getPreferencesValue(): T = get(key, defaultValue) ?: defaultValue +} \ No newline at end of file From 989db7a890fba20452691edf9a505038cf3c0b49 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mathieu=20M=C3=A9a?= Date: Wed, 29 Apr 2026 14:57:33 -0400 Subject: [PATCH 4/9] PR comments... --- .../android/commons/PreferenceUtils.java | 294 +++++++++--------- .../android/commons/pref/PreferencesExt.kt | 2 +- 2 files changed, 148 insertions(+), 148 deletions(-) diff --git a/src/main/java/org/mtransit/android/commons/PreferenceUtils.java b/src/main/java/org/mtransit/android/commons/PreferenceUtils.java index 35e45a98..a3258a52 100644 --- a/src/main/java/org/mtransit/android/commons/PreferenceUtils.java +++ b/src/main/java/org/mtransit/android/commons/PreferenceUtils.java @@ -135,148 +135,132 @@ public static String getPREFS_AGENCY_POIS_SHOWING_LIST_INSTEAD_OF_MAP(@NonNull S public static final boolean PREFS_KEEP_MODULE_APP_LAUNCHER_ICON_DEFAULT = true; public static final String PREFS_KEEP_MODULE_APP_LAUNCHER_ICON = "pKeepModuleAppLauncherIcon"; - @SuppressWarnings("deprecation") - @WorkerThread - @NonNull - public static SharedPreferences getPrefDefault(@NonNull Context context) { - return PreferenceManager.getDefaultSharedPreferences(context); - } + // region Common @WorkerThread - public static int getPrefDefault(@Nullable Context context, @NonNull String prefKey, int defaultValue) { - if (context == null) { - return defaultValue; - } - return getPref(getPrefDefault(context), prefKey, defaultValue); + private static int getPref(SharedPreferences sharedPreferences, String prefKey, int defaultValue) { + return sharedPreferences.getInt(prefKey, defaultValue); } @WorkerThread - public static long getPrefDefault(@Nullable Context context, @NonNull String prefKey, long defaultValue) { - if (context == null) { - return defaultValue; - } - return getPref(getPrefDefault(context), prefKey, defaultValue); + private static boolean getPref(SharedPreferences sharedPreferences, String prefKey, boolean defaultValue) { + return sharedPreferences.getBoolean(prefKey, defaultValue); } @WorkerThread - @Nullable - public static String getPrefDefault(@Nullable Context context, @NonNull String prefKey, @Nullable String defaultValue) { - if (context == null) { - MTLog.w(LOG_TAG, "Context null, using default value '%s' for preference '%s'!", defaultValue, prefKey); - return defaultValue; - } - return getPref(getPrefDefault(context), prefKey, defaultValue); + private static long getPref(SharedPreferences sharedPreferences, String prefKey, long defaultValue) { + return sharedPreferences.getLong(prefKey, defaultValue); } + @Nullable @WorkerThread - @NonNull - public static String getPrefDefaultNN(@NonNull Context context, @NonNull String prefKey, @NonNull String defaultValue) { - return getPref(getPrefDefault(context), prefKey, defaultValue); + private static Set getPref(SharedPreferences sharedPreferences, String prefKey, Set defaultValue) { + return sharedPreferences.getStringSet(prefKey, defaultValue); } @WorkerThread - public static boolean getPrefDefault(@Nullable Context context, @NonNull String prefKey, boolean defaultValue) { - if (context == null) { - MTLog.w(LOG_TAG, "Context null, using default value '%s' for preference '%s'!", defaultValue, prefKey); - return defaultValue; - } - return getPref(getPrefDefault(context), prefKey, defaultValue); + private static String getPref(SharedPreferences sharedPreferences, String prefKey, String defaultValue) { + return sharedPreferences.getString(prefKey, defaultValue); } @WorkerThread - public static boolean hasPrefDefault(@Nullable Context context, @NonNull String prefKey) { - if (context == null) { - return false; + private static void savePref(@NonNull SharedPreferences sharedPreferences, @NonNull String prefKey, @Nullable Integer newValue) { + final SharedPreferences.Editor editor = sharedPreferences.edit(); + if (newValue == null) { + editor.remove(prefKey); + } else { + editor.putInt(prefKey, newValue); } - return getPrefDefault(context).contains(prefKey); + editor.apply(); } @WorkerThread - public static int getPrefLcl(@Nullable Context context, @NonNull String prefKey, int defaultValue) { - if (context == null) { - return defaultValue; + private static void savePref(@NonNull SharedPreferences sharedPreferences, @NonNull String prefKey, @Nullable Boolean newValue) { + final SharedPreferences.Editor editor = sharedPreferences.edit(); + if (newValue == null) { + editor.remove(prefKey); + } else { + editor.putBoolean(prefKey, newValue); } - return getPref(getPrefLcl(context), prefKey, defaultValue); + editor.apply(); } @WorkerThread - public static boolean getPrefLcl(@Nullable Context context, @NonNull String prefKey, boolean defaultValue) { - if (context == null) { - return defaultValue; + private static void savePref(@NonNull SharedPreferences sharedPreferences, @NonNull String prefKey, @Nullable Long newValue) { + final SharedPreferences.Editor editor = sharedPreferences.edit(); + if (newValue == null) { + editor.remove(prefKey); + } else { + editor.putLong(prefKey, newValue); } - return getPref(getPrefLcl(context), prefKey, defaultValue); + editor.apply(); } @WorkerThread - public static long getPrefLcl(@Nullable Context context, @NonNull String prefKey, long defaultValue) { - if (context == null) { - return defaultValue; - } - return getPref(getPrefLcl(context), prefKey, defaultValue); + private static void savePref(@NonNull SharedPreferences sharedPreferences, @NonNull String prefKey, @Nullable String newValue) { + final SharedPreferences.Editor editor = sharedPreferences.edit(); + editor.putString(prefKey, newValue); + editor.apply(); } @WorkerThread - @Nullable - public static String getPrefLcl(@Nullable Context context, @NonNull String prefKey, @Nullable String defaultValue) { - if (context == null) { - return defaultValue; - } - return getPref(getPrefLcl(context), prefKey, defaultValue); + private static void savePref(@NonNull SharedPreferences sharedPreferences, @NonNull String prefKey, @Nullable Set newValue) { + final SharedPreferences.Editor editor = sharedPreferences.edit(); + editor.putStringSet(prefKey, newValue); + editor.apply(); } - @WorkerThread - @NonNull - public static String getPrefLclNN(@NonNull Context context, @NonNull String prefKey, @NonNull String defaultValue) { - return getPref(getPrefLcl(context), prefKey, defaultValue); - } + // endregion Common + + // region Default @WorkerThread - @Nullable - public static Set getPrefLcl(@Nullable Context context, @NonNull String prefKey, @Nullable Set defaultValue) { - if (context == null) { - return defaultValue; - } - return getPref(getPrefLcl(context), prefKey, defaultValue); + @NonNull + public static SharedPreferences getPrefDefault(@NonNull Context context) { + return PreferenceManager.getDefaultSharedPreferences(context); } @WorkerThread - @NonNull - public static SharedPreferences getPrefLcl(@NonNull Context context) { - return context.getSharedPreferences(LCL_PREF_NAME, Context.MODE_PRIVATE); + public static int getPrefDefault(@Nullable Context context, @NonNull String prefKey, int defaultValue) { + if (context == null) return defaultValue; + return getPref(getPrefDefault(context), prefKey, defaultValue); } @WorkerThread - public static boolean hasPrefLcl(@Nullable Context context, @NonNull String prefKey) { - if (context == null) { - return false; - } - return getPrefLcl(context).contains(prefKey); + public static long getPrefDefault(@Nullable Context context, @NonNull String prefKey, long defaultValue) { + if (context == null) return defaultValue; + return getPref(getPrefDefault(context), prefKey, defaultValue); } @WorkerThread - private static int getPref(SharedPreferences sharedPreferences, String prefKey, int defaultValue) { - return sharedPreferences.getInt(prefKey, defaultValue); + @Nullable + public static String getPrefDefault(@Nullable Context context, @NonNull String prefKey, @Nullable String defaultValue) { + if (context == null) return defaultValue; + return getPref(getPrefDefault(context), prefKey, defaultValue); } @WorkerThread - private static boolean getPref(SharedPreferences sharedPreferences, String prefKey, boolean defaultValue) { - return sharedPreferences.getBoolean(prefKey, defaultValue); + @NonNull + public static String getPrefDefaultNN(@NonNull Context context, @NonNull String prefKey, @NonNull String defaultValue) { + return getPref(getPrefDefault(context), prefKey, defaultValue); } @WorkerThread - private static long getPref(SharedPreferences sharedPreferences, String prefKey, long defaultValue) { - return sharedPreferences.getLong(prefKey, defaultValue); + public static boolean getPrefDefault(@Nullable Context context, @NonNull String prefKey, boolean defaultValue) { + if (context == null) return defaultValue; + return getPref(getPrefDefault(context), prefKey, defaultValue); } - @Nullable @WorkerThread - private static Set getPref(SharedPreferences sharedPreferences, String prefKey, Set defaultValue) { - return sharedPreferences.getStringSet(prefKey, defaultValue); + public static boolean hasPrefDefault(@Nullable Context context, @NonNull String prefKey) { + if (context == null) return false; + return getPrefDefault(context).contains(prefKey); } @WorkerThread - private static String getPref(SharedPreferences sharedPreferences, String prefKey, String defaultValue) { - return sharedPreferences.getString(prefKey, defaultValue); + public static void savePrefDefaultSync(@Nullable final Context context, @NonNull final String prefKey, final int newValue) { + if (context == null) return; + savePref(getPrefDefault(context), prefKey, newValue); } @AnyThread @@ -296,6 +280,12 @@ protected Void doInBackgroundMT(Void... params) { }.executeOnExecutor(TaskUtils.THREAD_POOL_EXECUTOR); } + @WorkerThread + public static void savePrefDefaultSync(@Nullable final Context context, @NonNull final String prefKey, final long newValue) { + if (context == null) return; + savePref(getPrefDefault(context), prefKey, newValue); + } + @AnyThread public static void savePrefDefaultAsync(@NonNull Context context, @NonNull String prefKey, long newValue) { new MTAsyncTask() { @@ -313,6 +303,12 @@ protected Void doInBackgroundMT(Void... params) { }.executeOnExecutor(TaskUtils.THREAD_POOL_EXECUTOR); } + @WorkerThread + public static void savePrefDefaultSync(@Nullable final Context context, @NonNull final String prefKey, @Nullable final Boolean newValue) { + if (context == null) return; + savePref(getPrefDefault(context), prefKey, newValue); + } + @AnyThread public static void savePrefDefaultAsync(@NonNull Context context, @NonNull String prefKey, @Nullable Boolean newValue) { new MTAsyncTask() { @@ -330,6 +326,12 @@ protected Void doInBackgroundMT(Void... params) { }.executeOnExecutor(TaskUtils.THREAD_POOL_EXECUTOR); } + @WorkerThread + public static void savePrefDefaultSync(@Nullable final Context context, @NonNull final String prefKey, @Nullable final String newValue) { + if (context == null) return; + savePref(getPrefDefault(context), prefKey, newValue); + } + @AnyThread public static void savePrefDefaultAsync(@NonNull Context context, @NonNull String prefKey, @Nullable String newValue) { new MTAsyncTask() { @@ -347,11 +349,63 @@ protected Void doInBackgroundMT(Void... params) { }.executeOnExecutor(TaskUtils.THREAD_POOL_EXECUTOR); } + // endregion Default + + // region Local + + @WorkerThread + public static int getPrefLcl(@Nullable Context context, @NonNull String prefKey, int defaultValue) { + if (context == null) return defaultValue; + return getPref(getPrefLcl(context), prefKey, defaultValue); + } + + @WorkerThread + public static boolean getPrefLcl(@Nullable Context context, @NonNull String prefKey, boolean defaultValue) { + if (context == null) return defaultValue; + return getPref(getPrefLcl(context), prefKey, defaultValue); + } + + @WorkerThread + public static long getPrefLcl(@Nullable Context context, @NonNull String prefKey, long defaultValue) { + if (context == null) return defaultValue; + return getPref(getPrefLcl(context), prefKey, defaultValue); + } + + @WorkerThread + @Nullable + public static String getPrefLcl(@Nullable Context context, @NonNull String prefKey, @Nullable String defaultValue) { + if (context == null) return defaultValue; + return getPref(getPrefLcl(context), prefKey, defaultValue); + } + + @WorkerThread + @NonNull + public static String getPrefLclNN(@NonNull Context context, @NonNull String prefKey, @NonNull String defaultValue) { + return getPref(getPrefLcl(context), prefKey, defaultValue); + } + + @WorkerThread + @Nullable + public static Set getPrefLcl(@Nullable Context context, @NonNull String prefKey, @Nullable Set defaultValue) { + if (context == null) return defaultValue; + return getPref(getPrefLcl(context), prefKey, defaultValue); + } + + @WorkerThread + @NonNull + public static SharedPreferences getPrefLcl(@NonNull Context context) { + return context.getSharedPreferences(LCL_PREF_NAME, Context.MODE_PRIVATE); + } + + @WorkerThread + public static boolean hasPrefLcl(@Nullable Context context, @NonNull String prefKey) { + if (context == null) return false; + return getPrefLcl(context).contains(prefKey); + } + @WorkerThread public static void savePrefLclSync(@Nullable final Context context, @NonNull final String prefKey, @Nullable final Integer newValue) { - if (context == null) { - return; - } + if (context == null) return; savePref(getPrefLcl(context), prefKey, newValue); } @@ -374,9 +428,7 @@ protected Void doInBackgroundMT(Void... params) { @WorkerThread public static void savePrefLclSync(@Nullable final Context context, @NonNull final String prefKey, @Nullable final Boolean newValue) { - if (context == null) { - return; - } + if (context == null) return; savePref(getPrefLcl(context), prefKey, newValue); } @@ -399,9 +451,7 @@ protected Void doInBackgroundMT(Void... params) { @WorkerThread public static void savePrefLclSync(@Nullable final Context context, @NonNull final String prefKey, @Nullable final Long newValue) { - if (context == null) { - return; - } + if (context == null) return; savePref(getPrefLcl(context), prefKey, newValue); } @@ -424,9 +474,7 @@ protected Void doInBackgroundMT(Void... params) { @WorkerThread public static void savePrefLclSync(@Nullable final Context context, @NonNull final String prefKey, @Nullable final String newValue) { - if (context == null) { - return; - } + if (context == null) return; savePref(getPrefLcl(context), prefKey, newValue); } @@ -447,12 +495,9 @@ protected Void doInBackgroundMT(Void... params) { }.executeOnExecutor(TaskUtils.THREAD_POOL_EXECUTOR); } - @WorkerThread public static void savePrefLclSync(@Nullable final Context context, @NonNull final String prefKey, @Nullable final Set newValue) { - if (context == null) { - return; - } + if (context == null) return; savePref(getPrefLcl(context), prefKey, newValue); } @@ -473,50 +518,5 @@ protected Void doInBackgroundMT(Void... params) { }.executeOnExecutor(TaskUtils.THREAD_POOL_EXECUTOR); } - @WorkerThread - private static void savePref(@NonNull SharedPreferences sharedPreferences, @NonNull String prefKey, @Nullable Integer newValue) { - SharedPreferences.Editor editor = sharedPreferences.edit(); - if (newValue == null) { - editor.remove(prefKey); - } else { - editor.putInt(prefKey, newValue); - } - editor.apply(); - } - - @WorkerThread - private static void savePref(@NonNull SharedPreferences sharedPreferences, @NonNull String prefKey, @Nullable Boolean newValue) { - SharedPreferences.Editor editor = sharedPreferences.edit(); - if (newValue == null) { - editor.remove(prefKey); - } else { - editor.putBoolean(prefKey, newValue); - } - editor.apply(); - } - - @WorkerThread - private static void savePref(@NonNull SharedPreferences sharedPreferences, @NonNull String prefKey, @Nullable Long newValue) { - SharedPreferences.Editor editor = sharedPreferences.edit(); - if (newValue == null) { - editor.remove(prefKey); - } else { - editor.putLong(prefKey, newValue); - } - editor.apply(); - } - - @WorkerThread - private static void savePref(@NonNull SharedPreferences sharedPreferences, @NonNull String prefKey, @Nullable String newValue) { - SharedPreferences.Editor editor = sharedPreferences.edit(); - editor.putString(prefKey, newValue); - editor.apply(); - } - - @WorkerThread - private static void savePref(@NonNull SharedPreferences sharedPreferences, @NonNull String prefKey, @Nullable Set newValue) { - SharedPreferences.Editor editor = sharedPreferences.edit(); - editor.putStringSet(prefKey, newValue); - editor.apply(); - } + // endregion Local } diff --git a/src/main/java/org/mtransit/android/commons/pref/PreferencesExt.kt b/src/main/java/org/mtransit/android/commons/pref/PreferencesExt.kt index 24de81c4..00c66fc4 100644 --- a/src/main/java/org/mtransit/android/commons/pref/PreferencesExt.kt +++ b/src/main/java/org/mtransit/android/commons/pref/PreferencesExt.kt @@ -35,4 +35,4 @@ inline fun SharedPreferences.liveData( notifyInitValue: Boolean = true, ): LiveData = object : PreferenceLiveData(this, key, notifyInitValue) { override fun getPreferencesValue(): T = get(key, defaultValue) ?: defaultValue -} \ No newline at end of file +} From 7b0b60a0b2a15c3d8cf33783b1f7a27899c3421b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mathieu=20M=C3=A9a?= Date: Wed, 29 Apr 2026 15:41:29 -0400 Subject: [PATCH 5/9] PR comments --- .../mtransit/android/commons/pref/PreferenceChangeLiveData.kt | 4 ++-- .../org/mtransit/android/commons/pref/PreferenceListener.kt | 4 +++- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/src/main/java/org/mtransit/android/commons/pref/PreferenceChangeLiveData.kt b/src/main/java/org/mtransit/android/commons/pref/PreferenceChangeLiveData.kt index 0c67702f..a1be8e8a 100644 --- a/src/main/java/org/mtransit/android/commons/pref/PreferenceChangeLiveData.kt +++ b/src/main/java/org/mtransit/android/commons/pref/PreferenceChangeLiveData.kt @@ -5,7 +5,7 @@ import androidx.lifecycle.LiveData class PreferenceChangeLiveData( private val preferences: SharedPreferences, -) : LiveData() { +) : LiveData() { private val listener: SharedPreferences.OnSharedPreferenceChangeListener by lazy { SharedPreferences.OnSharedPreferenceChangeListener { _, key -> @@ -24,4 +24,4 @@ class PreferenceChangeLiveData( } } -fun SharedPreferences.preferenceChangeLiveData(): LiveData = PreferenceChangeLiveData(this) +fun SharedPreferences.preferenceChangeLiveData(): LiveData = PreferenceChangeLiveData(this) diff --git a/src/main/java/org/mtransit/android/commons/pref/PreferenceListener.kt b/src/main/java/org/mtransit/android/commons/pref/PreferenceListener.kt index 281a67fc..8e3ba5e1 100644 --- a/src/main/java/org/mtransit/android/commons/pref/PreferenceListener.kt +++ b/src/main/java/org/mtransit/android/commons/pref/PreferenceListener.kt @@ -1,14 +1,16 @@ package org.mtransit.android.commons.pref import android.content.SharedPreferences +import androidx.annotation.MainThread class PreferenceListener( private val preferences: SharedPreferences, notifyInitValue: Boolean, private val valueKey: String, private val getPreferencesValue: () -> T, + @MainThread private val setValue: (T) -> Unit, - private val getValue: () -> T, + private val getValue: () -> T?, ) : SharedPreferences.OnSharedPreferenceChangeListener { private var needCheckWhenRegister = false From c086dae4df9c6db0701a46be7118e5d8849c20a8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mathieu=20M=C3=A9a?= Date: Thu, 30 Apr 2026 09:13:33 -0400 Subject: [PATCH 6/9] Update src/main/java/org/mtransit/android/commons/pref/PreferenceChangeLiveData.kt Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com> --- .../mtransit/android/commons/pref/PreferenceChangeLiveData.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/org/mtransit/android/commons/pref/PreferenceChangeLiveData.kt b/src/main/java/org/mtransit/android/commons/pref/PreferenceChangeLiveData.kt index a1be8e8a..30e7452c 100644 --- a/src/main/java/org/mtransit/android/commons/pref/PreferenceChangeLiveData.kt +++ b/src/main/java/org/mtransit/android/commons/pref/PreferenceChangeLiveData.kt @@ -9,7 +9,7 @@ class PreferenceChangeLiveData( private val listener: SharedPreferences.OnSharedPreferenceChangeListener by lazy { SharedPreferences.OnSharedPreferenceChangeListener { _, key -> - value = key + postValue(key) } } From 07adfd24d337853d649a620dd587396b8fd05746 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mathieu=20M=C3=A9a?= Date: Thu, 30 Apr 2026 09:17:02 -0400 Subject: [PATCH 7/9] PR comments --- .../android/commons/pref/PreferenceListener.kt | 12 +++++++----- .../android/commons/pref/PreferenceLiveData.kt | 4 +++- .../mtransit/android/commons/pref/PreferencesExt.kt | 3 +++ 3 files changed, 13 insertions(+), 6 deletions(-) diff --git a/src/main/java/org/mtransit/android/commons/pref/PreferenceListener.kt b/src/main/java/org/mtransit/android/commons/pref/PreferenceListener.kt index 8e3ba5e1..065a32e7 100644 --- a/src/main/java/org/mtransit/android/commons/pref/PreferenceListener.kt +++ b/src/main/java/org/mtransit/android/commons/pref/PreferenceListener.kt @@ -1,22 +1,24 @@ package org.mtransit.android.commons.pref import android.content.SharedPreferences -import androidx.annotation.MainThread +import androidx.annotation.AnyThread class PreferenceListener( private val preferences: SharedPreferences, notifyInitValue: Boolean, private val valueKey: String, + @AnyThread private val getPreferencesValue: () -> T, - @MainThread - private val setValue: (T) -> Unit, + @AnyThread + private val postValue: (T) -> Unit, + @AnyThread private val getValue: () -> T?, ) : SharedPreferences.OnSharedPreferenceChangeListener { private var needCheckWhenRegister = false init { if (notifyInitValue) { - setValue(getPreferencesValue()) + postValue(getPreferencesValue()) } } @@ -40,6 +42,6 @@ class PreferenceListener( private fun updateValue(newValue: T) { if (getValue() == newValue) return - setValue(newValue) + postValue(newValue) } } diff --git a/src/main/java/org/mtransit/android/commons/pref/PreferenceLiveData.kt b/src/main/java/org/mtransit/android/commons/pref/PreferenceLiveData.kt index cb91458f..b480ee6a 100644 --- a/src/main/java/org/mtransit/android/commons/pref/PreferenceLiveData.kt +++ b/src/main/java/org/mtransit/android/commons/pref/PreferenceLiveData.kt @@ -1,6 +1,7 @@ package org.mtransit.android.commons.pref import android.content.SharedPreferences +import androidx.annotation.AnyThread import androidx.lifecycle.LiveData // https://github.com/Jintin/PreferencesExtension/blob/master/preferences/src/main/java/com/jintin/preferencesextension/PreferenceLiveData.kt @@ -16,7 +17,7 @@ abstract class PreferenceLiveData( notifyInitValue, key, ::getPreferencesValue, - ::setValue, + ::postValue, ::getValue ) } @@ -31,6 +32,7 @@ abstract class PreferenceLiveData( listener.unregister() } + @AnyThread abstract fun getPreferencesValue(): T } diff --git a/src/main/java/org/mtransit/android/commons/pref/PreferencesExt.kt b/src/main/java/org/mtransit/android/commons/pref/PreferencesExt.kt index 00c66fc4..aa143392 100644 --- a/src/main/java/org/mtransit/android/commons/pref/PreferencesExt.kt +++ b/src/main/java/org/mtransit/android/commons/pref/PreferencesExt.kt @@ -1,6 +1,7 @@ package org.mtransit.android.commons.pref import android.content.SharedPreferences +import androidx.annotation.AnyThread import androidx.lifecycle.LiveData // https://github.com/Jintin/PreferencesExtension/blob/master/preferences/src/main/java/com/jintin/preferencesextension/PreferencesExtension.kt @@ -26,6 +27,7 @@ inline fun SharedPreferences.liveDataN( defaultValue: T? = null, notifyInitValue: Boolean = true, ): LiveData = object : PreferenceLiveData(this, key, notifyInitValue) { + @AnyThread override fun getPreferencesValue(): T? = get(key, defaultValue) } @@ -34,5 +36,6 @@ inline fun SharedPreferences.liveData( defaultValue: T, notifyInitValue: Boolean = true, ): LiveData = object : PreferenceLiveData(this, key, notifyInitValue) { + @AnyThread override fun getPreferencesValue(): T = get(key, defaultValue) ?: defaultValue } From ddba710c1a923455367bc4f2f9f16edce316eeba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mathieu=20M=C3=A9a?= Date: Thu, 30 Apr 2026 09:40:23 -0400 Subject: [PATCH 8/9] PR comments --- .../android/commons/pref/PreferenceListener.kt | 5 ++++- .../android/commons/pref/PreferenceLiveData.kt | 13 +++++++------ 2 files changed, 11 insertions(+), 7 deletions(-) diff --git a/src/main/java/org/mtransit/android/commons/pref/PreferenceListener.kt b/src/main/java/org/mtransit/android/commons/pref/PreferenceListener.kt index 065a32e7..ac0af654 100644 --- a/src/main/java/org/mtransit/android/commons/pref/PreferenceListener.kt +++ b/src/main/java/org/mtransit/android/commons/pref/PreferenceListener.kt @@ -2,6 +2,7 @@ package org.mtransit.android.commons.pref import android.content.SharedPreferences import androidx.annotation.AnyThread +import androidx.annotation.MainThread class PreferenceListener( private val preferences: SharedPreferences, @@ -9,6 +10,8 @@ class PreferenceListener( private val valueKey: String, @AnyThread private val getPreferencesValue: () -> T, + @MainThread + private val setValue: (T) -> Unit, @AnyThread private val postValue: (T) -> Unit, @AnyThread @@ -18,7 +21,7 @@ class PreferenceListener( init { if (notifyInitValue) { - postValue(getPreferencesValue()) + setValue(getPreferencesValue()) } } diff --git a/src/main/java/org/mtransit/android/commons/pref/PreferenceLiveData.kt b/src/main/java/org/mtransit/android/commons/pref/PreferenceLiveData.kt index b480ee6a..3a2d2c75 100644 --- a/src/main/java/org/mtransit/android/commons/pref/PreferenceLiveData.kt +++ b/src/main/java/org/mtransit/android/commons/pref/PreferenceLiveData.kt @@ -13,12 +13,13 @@ abstract class PreferenceLiveData( private val listener by lazy { PreferenceListener( - preferences, - notifyInitValue, - key, - ::getPreferencesValue, - ::postValue, - ::getValue + preferences = preferences, + notifyInitValue = notifyInitValue, + valueKey = key, + getPreferencesValue = ::getPreferencesValue, + setValue = ::setValue, + postValue = ::postValue, + getValue = ::getValue ) } From 39a692e34e56e58679d2ea9b427f733759de26cb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mathieu=20M=C3=A9a?= Date: Thu, 30 Apr 2026 10:07:11 -0400 Subject: [PATCH 9/9] PR comment --- .../org/mtransit/android/commons/PreferenceUtils.java | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/main/java/org/mtransit/android/commons/PreferenceUtils.java b/src/main/java/org/mtransit/android/commons/PreferenceUtils.java index a3258a52..17692cce 100644 --- a/src/main/java/org/mtransit/android/commons/PreferenceUtils.java +++ b/src/main/java/org/mtransit/android/commons/PreferenceUtils.java @@ -138,28 +138,28 @@ public static String getPREFS_AGENCY_POIS_SHOWING_LIST_INSTEAD_OF_MAP(@NonNull S // region Common @WorkerThread - private static int getPref(SharedPreferences sharedPreferences, String prefKey, int defaultValue) { + private static int getPref(@NonNull SharedPreferences sharedPreferences, @NonNull String prefKey, int defaultValue) { return sharedPreferences.getInt(prefKey, defaultValue); } @WorkerThread - private static boolean getPref(SharedPreferences sharedPreferences, String prefKey, boolean defaultValue) { + private static boolean getPref(@NonNull SharedPreferences sharedPreferences, @NonNull String prefKey, boolean defaultValue) { return sharedPreferences.getBoolean(prefKey, defaultValue); } @WorkerThread - private static long getPref(SharedPreferences sharedPreferences, String prefKey, long defaultValue) { + private static long getPref(@NonNull SharedPreferences sharedPreferences, @NonNull String prefKey, long defaultValue) { return sharedPreferences.getLong(prefKey, defaultValue); } @Nullable @WorkerThread - private static Set getPref(SharedPreferences sharedPreferences, String prefKey, Set defaultValue) { + private static Set getPref(@NonNull SharedPreferences sharedPreferences, @NonNull String prefKey, @Nullable Set defaultValue) { return sharedPreferences.getStringSet(prefKey, defaultValue); } @WorkerThread - private static String getPref(SharedPreferences sharedPreferences, String prefKey, String defaultValue) { + private static String getPref(@NonNull SharedPreferences sharedPreferences, @NonNull String prefKey, @Nullable String defaultValue) { return sharedPreferences.getString(prefKey, defaultValue); }