Intereting Posts
Показывать SearchWidget в ActionBar, если пользователь нажимает кнопку поиска устройства Последняя проблема удаления утилиты Android RecyclerView (runtime) Масштабирование ImageView TOP_CROP Пользовательские маркеры, показывающие белый цвет на некоторых устройствах (Google Maps v3 Android SDK) Получение «Фрагмент не создавал вид» после присоединения другого фрагмента без пользовательского интерфейса Android NFC Intents не запускают мою деятельность Сбой инициализации SDL, причина в том, что нет доступного видеоустройства К сожалению, приложение остановилось в Android Emulator Распечатайте значение логического значения в Log Android: Фрагменты, SQLite и Loaders Как заставить Android-устройство вибрировать? Когда использовать JNIEXPORT и JNICALL в Android NDK? Canvas 'drawLine и drawRect не включают конечную позицию? Как обнаружить биржевой браузер Android API данных Youtube: получить доступ к медиапотоку и воспроизведению (JAVA)

SharedPreference, установленное в SyncAdapter, не обновлено в Activity?

Я изменяю и передаю SharedPreference в моем SyncAdapter после успешной синхронизации, но я не вижу обновленного значения, когда получаю доступ к предпочтению в своей работе (скорее, я вижу старое значение). Что я делаю не так? Разные контексты?

Мой SyncAdapter, где я обновляю предпочтение:

class SyncAdapter extends AbstractThreadedSyncAdapter { private int PARTICIPANT_ID; private final Context mContext; private final ContentResolver mContentResolver; public SyncAdapter(Context context, boolean autoInitialize) { super(context, autoInitialize); mContext = context; mContentResolver = context.getContentResolver(); } public SyncAdapter(Context context, boolean autoInitialize, boolean allowParallelSyncs) { super(context, autoInitialize, allowParallelSyncs); mContext = context; mContentResolver = context.getContentResolver(); } @Override public void onPerformSync(Account account, Bundle extras, String authority, ContentProviderClient provider, SyncResult syncResult) { final SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(mContext); PARTICIPANT_ID = Integer.parseInt(prefs.getString("participant_id", "0")); if (success) { // save and set the new participant id PARTICIPANT_ID = newParticipantId; prefs.edit().putString("participant_id", String.valueOf(newParticipantId)).commit(); } } } 

Служба, инициализирующая SyncAdapter с помощью ApplicationContext:

 public class SyncService extends Service { private static final Object sSyncAdapterLock = new Object(); private static SyncAdapter sSyncAdapter = null; @Override public void onCreate() { synchronized (sSyncAdapterLock) { if (sSyncAdapter == null) { sSyncAdapter = new SyncAdapter(getApplicationContext(), false); } } } @Override public IBinder onBind(Intent intent) { return sSyncAdapter.getSyncAdapterBinder(); } } 

Статическая функция в приложении, вызываемая Activity, которая проверяет SharedPreference. Это не возвращает значение, зафиксированное в SyncAdapter, но старое значение. (Мои настройкиActivity и другие действия также используют старое значение.):

 public static boolean isUserLoggedIn(Context ctx) { final SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(ctx); int participantId = Integer.parseInt(prefs.getString("participant_id", "0")); LOGD("dg_Utils", "isUserLoggedIn.participantId: " + participantId);// TODO if (participantId <= 0) { ctx.startActivity(new Intent(ctx, LoginActivity.class).addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP)); return false; } return true; } 

UPDATE: я получаю новое значение, когда полностью закрываю приложение (проведите его по экрану из приложений). У меня также есть SharedPreferenceChangeListener, который не запускается, когда предпочтение обновляется.

 private final SharedPreferences.OnSharedPreferenceChangeListener mParticipantIDPrefChangeListener = new SharedPreferences.OnSharedPreferenceChangeListener() { public void onSharedPreferenceChanged(SharedPreferences prefs, String key) { if (key.equals("participant_id")) { LOGI(TAG, "participant_id has changed, requesting to restart the loader."); mRestartLoader = true; } } }; @Override public void onActivityCreated(Bundle savedInstanceState) { super.onActivityCreated(savedInstanceState); // subscribe to the participant_id change lister final SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(getActivity()); PARTICIPANT_ID = Integer.parseInt(prefs.getString("participant_id", "0")); prefs.registerOnSharedPreferenceChangeListener(mParticipantIDPrefChangeListener); } 

Solutions Collecting From Web of "SharedPreference, установленное в SyncAdapter, не обновлено в Activity?"

Хорошо, я понял это с помощью @Titus и после некоторых исследований и собрал решение для своей проблемы.

Причина, почему DefaultSharedPreferences одного и того же Context не обновляется, заключается в том, что я указал SyncService для запуска в своем собственном процессе в AndroidManifest.xml (см. Ниже). Следовательно, начиная с Android 2.3, другой процесс блокируется от доступа к обновленному файлу SharedPreferences (см. Этот ответ и документы Android в Context.MODE_MULTI_PROCESS ).

  <service android:name=".sync.SyncService" android:exported="true" android:process=":sync" tools:ignore="ExportedService" > <intent-filter> <action android:name="android.content.SyncAdapter" /> </intent-filter> <meta-data android:name="android.content.SyncAdapter" android:resource="@xml/syncadapter" /> </service> 

Поэтому мне пришлось установить MODE_MULTI_PROCESS при доступе к SharedPreferences как в SyncAdapter и в процессе пользовательского интерфейса моего приложения. Поскольку я широко использовал PreferenceManager.getDefaultSharedPreferences(Context) во всем приложении, я написал метод утилиты и заменил все вызовы PreferenceManager.getDefaultSharedPreferences(Context) с помощью этого метода (см. Ниже). Имя файла настроек по умолчанию является жестко запрограммированным и выводится из исходного кода Android и этого ответа .

 public static SharedPreferences getDefaultSharedPreferencesMultiProcess( Context context) { return context.getSharedPreferences( context.getPackageName() + "_preferences", Context.MODE_PRIVATE | Context.MODE_MULTI_PROCESS); } 

Поскольку SharedPreferences не являются безопасными для процесса, я бы не рекомендовал использовать AbstractThreadedSyncAdapter в другом процессе, если вам это действительно не нужно.

Зачем мне нужно несколько процессов в моем приложении?

Решение

Удалите android:process=":sync" из Сервиса, который вы заявили в своем манифесте!

 <service android:name=".sync.SyncService" android:exported="true" android:process=":sync" tools:ignore="ExportedService" > <intent-filter> <action android:name="android.content.SyncAdapter" /> </intent-filter> <meta-data android:name="android.content.SyncAdapter" android:resource="@xml/syncadapter" /> </service> 

В моем случае я пытался получить доступ к SharedPreferences из службы, запущенной BroadcastReceiver.

Я удалил android:process=":remote" из объявления в AndroidManifest.xml, чтобы заставить его работать.

 <receiver android:process=":remote" android:name=".Alarm"> </receiver>