Android Shared Preferences - The Vapor Way

Having to obtain a SharedPreferences.Editor instance everytime before you want to alter SharedPreferences in Android is somewhat trivial.

As such, VaporSharedPreferences serves to unify the reading and writing of shared preferences in your code, providing Android app developers with one simple API.

Additionally, like VaporBundle and VaporIntent, VaporSharedPreferences contains an overloaded .put(...) method that will resolve the correct overload for the datatype given.

This is handy as it makes passing data to these classes quick and easy. Moreover like the majority of the Vapor Android framework, VaporSharedPreferences is also fluent so you can chain successive method calls!

Singleton

Like Android SharedPreferences, VaporSharedPreferences utilises the Singleton pattern to ensure you are only ever working with one instance of this class.

$.prefs(...)

To obtain the Singleton instance use $.prefs(...) from anywhere in your code.

The Vapor Android framework provides no methods to set the underlying SharedPreferences mode, and assumes Context.MODE_PRIVATE. This is inline with Android docs that deprecated Context.MODE_WORLD_READABLE and Context.MODE_WORLD_WRITEABLE in Android API 17, and discourage the use of Context.MODE_MULTI_PROCESS as a form of communication between processes.

Obtaining A Handle

The $ facade exposes several convenience methods to obtain a reference:

  • $.prefs() assumes you require access to the VaporSharedPreferences for the current Activity context
  • $.prefs(String) retrieves the VaporSharedPreferences for the given file name, creating it first if the file does not exist
  • $.prefs(SharedPreferences) returns a VaporSharedPreferences whereby the underlying SharedPreferences is set to the given SharedPreferences object
The VaporSharedPreferences class itself only supports .prefs(). The $.prefs(...) overloads use .prefs().file(...) to set the underlying SharedPreferences resource for you

Altering Preferences

The overloaded .put(...) method is one of the strengths of VaporSharedPreferences as you can use .put(...) with any supported datatype.

.put(...) is overloaded with all the supported data types for SharedPreferences, and is fluent.

This means you can put multiple items in to your shared preferences with jQuery style chained calls:

	$.prefs() 
		.put("firstName", "John")
		.put("lastName", "Smith")
		.put("age", 24)
		.put("gender", 'M');

Notice also how we used the .put(...) seamlessly with different datatypes, namely String, int and char!

Retrieving Preferences

To retrieve a preference use one of the appropriate .get___(String) methods for the expected return type.

In the following example we see how we use specific .get___(String) methods to retrieve the applicable data type:

    // Retrieve a Float
	Float float = $.prefs().getFloat("someKey");

    // Retrieve a Set of Strings
	Set<String> strings = $.prefs().getStrings("someOtherKey");

Notable Helper Methods

The following methods are useful to know when working with VaporSharedPreferences:

async(boolean)

The standard Android SharedPreferences API gives you the choice of saving changes with both .apply() and .commit() methods. The former is asynchronous, whereas the latter is performed as a blocking operation.

The Vapor Android framework simplifies this functionality by providing a single method, .async(boolean).

You can of course change the async setting adhoc, which is particularly handy if you suddenly have a lot of data to write and don't want to hold up the current thread.

To make the write operation asynchronous (analogous to using .apply()) set .async(true), and use .async(false) to perform writes as a blocking operation (analogous to .commit()).

To query the current async setting use .async().

autoSave(boolean) and save()

The .save() method will write any outstanding changes to disk. However, by default VaporSharedPreferences will automatically save any changes you make to shared preferences so you needn't call .save() at all!

Whilst this is helpful for most cases, autoSaving can be inefficient if you are chaining a lot of .put(...) invocations together in one go.

In this case you might prefer to use the following chain style:

	$.prefs() 
		.autoSave(false) // turn off autoSave as we're going to put a lot of data at once
		.put("someKey", 1)
		.put("anotherKey", true)
		...
		.put("someOtherKey", "Hello World!")
		.autoSave(true) // turn autoSave back on so final 'put' saves prior changes
		.put("andFinally", 450);

Notice how autoSave is reenabled in the penultimate method of the chain. This means that the final .put(...) invocation will trigger all changes to be saved back to disk.

Alternatively you could use .save().autoSave(true) at the end of your chain, though this has the additional overhead cost of an extra method call.

If you choose to disable autoSave then you must call .save() whenever you wish to write your preference changes to disk. As noted above, you can set whether this is done asynchronously at any time using .async(boolean).