在ActivAdapter中提交的SharedPreference是否在Activity中未更新? [英] SharedPreference committed in SyncAdapter not updated in Activity?

查看:147
本文介绍了在ActivAdapter中提交的SharedPreference是否在Activity中未更新?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

成功同步后,我正在SyncAdapter中更改并提交SharedPreference,但是当我在Activity中访问首选项时,我看不到更新的值(而是看到了旧值).我究竟做错了什么?不同的背景?

I am changing and committing a SharedPreference in my SyncAdapter after successful sync, but I am not seeing the updated value when I access the preference in my Activity (rather I am seeing the old value). What am I doing wrong? Different Contexts?

我的SyncAdapter,其中更新了首选项:

My SyncAdapter where I update the preference:

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();
        }
    }
}

该服务使用ApplicationContext初始化SyncAdapter:

The Service initializing the SyncAdapter with the 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调用的Application中的一个静态函数,用于检查SharedPreference.这不会返回SyncAdapter中提交的值,而是返回旧值.(我的SettingsActivity和其他活动"也使用旧值.):

A static function within the Application called by the Activity that checks the SharedPreference. This does not return the value committed in the SyncAdapter, but the old value. (My SettingsActivity and other Activities also use the old value.):

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;
}

更新:当我完全关闭应用程序(从正在运行的应用程序中擦除)时,我得到了新的价值.我也有一个SharedPreferenceChangeListener,更新首选项时不会触发.

UPDATE: I am getting the new value when I completely close the app (swipe it from the apps running). I also have a SharedPreferenceChangeListener, which is not fired when the preference is updated.

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);
}

推荐答案

好吧,我在@Titus的帮助下自己弄清楚了,经过一些研究,为我的问题拼凑了解决方案.

Ok, I figured it out myself with @Titus help and after some research and pieced together a solution for my problem.

未更新同一 Context DefaultSharedPreferences 的原因是,我已指定 SyncService 在其自己的进程中运行 AndroidManifest.xml (请参见下文).因此,从Android 2.3开始,其他进程将无法访问更新的 SharedPreferences 文件(请参阅此答案 Context.MODE_MULTI_PROCESS ).

The reason why the DefaultSharedPreferences of the same Context are not updated is that I have specified the SyncService to run in its own process in the AndroidManifest.xml (see below). Hence, starting from Android 2.3, the other process is blocked from accessing the updated SharedPreferences file (see this answer and the Android docs on 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>

因此,在 SyncAdapter 和应用程序的UI进程中访问 SharedPreferences 时,我必须设置 MODE_MULTI_PROCESS .因为我在整个应用程序中都广泛使用了 PreferenceManager.getDefaultSharedPreferences(Context),所以我编写了一个实用程序方法,并用此方法替换了 PreferenceManager.getDefaultSharedPreferences(Context)的所有调用(请参见以下).首选项文件的默认名称是硬编码的,并从这个答案.

So I had to set MODE_MULTI_PROCESS when accessing the SharedPreferences both in the SyncAdapter and in the UI process of my app. Because I've used PreferenceManager.getDefaultSharedPreferences(Context) extensively throughout the app I wrote a utility method and replaced all calls of PreferenceManager.getDefaultSharedPreferences(Context) with this method (see below). The default name of the preferences file is hardcoded and derived from the Android source code and this answer.

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

这篇关于在ActivAdapter中提交的SharedPreference是否在Activity中未更新?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆