4

In my Application ,upon login I am saving the user details like (userName, Id ,email etc.) in a sharedPreference file, so that I can access those anywhere in my application, I am doing it like this

public void put(String fileName, String key, String value)
{
    SharedPreferences sharedPref = getContext().getSharedPreferences(fileName, Context.MODE_PRIVATE);
    SharedPreferences.Editor editor = sharedPref.edit();
    editor.putString(key, value);
    editor.commit();
}

now I have spawned a different thread, which will run independently (something like Sync), I am accessing sharedPreference like this ,

mContext.getSharedPreferences(fileName, Context.MODE_PRIVATE);

but all the values in this particular preference are returned as null, am I doing anything wrong,

PS :- If I kill the app and again same thread gets spawned, I can acess the values (its quite strange, but this is happening, i.e. when user logs in for first time , these details are not accessible)

feels like sync issue with SharedPreferences , can anyone help on this?

Vihar
  • 3,626
  • 2
  • 24
  • 47
  • 1
    I think [this](http://stackoverflow.com/questions/4693387/sharedpreferences-and-thread-safety) question resolved your problem – Mohammad Hossein Gerami Oct 26 '15 at 08:23
  • OP didn't say anything about processes, only threads. Or maybe he modified app's manifest to spawn services in processes instead of threads in the same process? @Vihar, can you confirm? – Trynkiewicz Mariusz Oct 27 '15 at 15:47
  • @TrynkiewiczMariusz you are right , I have spawned a service which is trying to read from sharedPreference file – Vihar Oct 28 '15 at 06:55
  • @Vihar In that case keep in mind what I said about the `MODE_MULTI_PROCESS` being deprecated... just sayin' – 4gus71n Oct 29 '15 at 14:23
  • follow up to @astinx comment https://github.com/grandcentrix/tray/issues/39 says using content provider is the way to go here on for this kind of use cases!! – Ramesh Nov 02 '15 at 05:55

4 Answers4

4

I think you've chosen the right way. Actually accessing shared preferences is just an I/O operation on a XML file stored in /data/data/pkg_name/preferences. Thus it's really making sense if you would like to access it in other threads than the UI.

However, you should make sure after each operation on shared preferences, you should commit the changes in underlying layers. First off you should beware of differences between apply() and commit().

Thus, you should first commit your changes and afterwards you can access it through another threads.

Community
  • 1
  • 1
frogatto
  • 28,539
  • 11
  • 83
  • 129
  • yes @abforce, you are right about commiting the changes, I have verified that all changes first are written into shared preference files and then it is accessed for reading, Put in log statements to verify this – Vihar Oct 27 '15 at 06:59
  • I just changed the mode of my shared preference to MODE_MULTI_PROCESS and it worked like charm! – Vihar Oct 28 '15 at 14:36
  • @Vihar "This constant was deprecated in API level 23." – frogatto Nov 02 '15 at 07:05
  • yes I am aware of that, but this will work as quick fix and buy me some time, till then I can implement ContentProviders – Vihar Nov 02 '15 at 07:39
1

Change MODE_PRIVATE to MODE_WORLD_READABLE.

Liran Peretz
  • 580
  • 8
  • 11
1

I'd the same issue some time ago trying to access my SharedPreference from a Service wich ran in It's own process. Here's how I solve it:

MultiProcessShared example:

public class GenericSharedPreferences {
public static final String TAG = GenericSharedPreferences.class.getSimpleName();

//region Logger
public static Logger sLogger;

static {
    sLogger = Logger.getLogger(TAG);
    if (BuildConfig.DEBUG)
        sLogger.setLevel(Level.ALL);
    else
        sLogger.setLevel(Level.OFF);
}
//endregion

public static MultiProcessShared.MultiProcessSharedPreferences getMultiProcessSharedReader(Context context) {
    return MultiProcessShared.getDefaultSharedPreferences(context);
}

public static MultiProcessShared.Editor getMultiProcessSharedWriter(Context context) {
    return MultiProcessShared.getDefaultSharedPreferences(context).edit();
}

}

My App SharedPreferences concrete implementation:

public class MyAppSharedPreferences extends GenericSharedPreferences {
...
//region Country
    private static final String SHARED_APP_COUNTRY = "shared-app-country";

    public static Country getCountry() {
        String isoCode = getMultiProcessSharedReader(MyApp.getInstance()).getString(SHARED_APP_COUNTRY);
        CountryEnum countryEnum = CountryEnum.fromIso(isoCode);
        if (countryEnum == null)
            return null;
        return countryEnum.getCountry();
    }

    public static void setCountry(String isoCode) {
        if (TextUtils.isEmpty(isoCode))
            getMultiProcessSharedReader(MyApp.getInstance()).removeString(SHARED_APP_COUNTRY);
        else
            getMultiProcessSharedWriter(MyApp.getInstance()).putString(SHARED_APP_COUNTRY, isoCode);
    }
    //endregion
...
}

MyApp is the application which I associated in the AndroidManifext.xml

Any question, feel free to ask!

4gus71n
  • 3,717
  • 3
  • 39
  • 66
  • I do not have a PREFERENCE_AUTHORITY setup for my app right now – Vihar Oct 28 '15 at 06:53
  • thanks for all your efforts, just one word from your file helped in solving my problem I just changed the mode of my shared preference to `MODE_MULTI_PROCESS` and it worked like charm! – Vihar Oct 28 '15 at 08:00
  • @Vihar Maybe is working for now, check [this](http://developer.android.com/reference/android/content/Context.html#MODE_MULTI_PROCESS) the constant `MODE_MULTI_PROCESS` is deprecated and doesn't ensure you that It'll work in all the cases. That was exactly what happened to me, my `Service` used to persist the values some times and some times didn't using this flag. – 4gus71n Oct 29 '15 at 12:36
1

The thread which was accessing the shared preference turned out to be in a service which was running in a different process,

so changing the shared preference mode to MODE_MULTI_PROCESS instead of MODE_PRIVATE worked perfectly,

Now I can access the shared preference normally

Thanks for all who tried!

Vihar
  • 3,626
  • 2
  • 24
  • 47