AnnoPref — make saving SharedPreferences easier

Tuan Chau
3 min readNov 24, 2016

I have been working on Android for years. Whenever making a get/set (or get/put) a field in the SharedPreferences file, I feel hard. It’s, sometimes, because I don’t know which name I should name the preference. Besides, my code would be messed with lots of string constants, and get/put of the SharedPreferences’ object will go along with those constants or I have to define (again) tons of get/set method.

The above reasons encouraged me to learn about Java annotation processor, then, implemented a shortcut way to define preferences’ field name as well as get/set/has functions. Just define a class with fields, AnnoPref will take the rest.

Okay, let’s take a look at this example: if we need to save two preferences for our user settings, one for the startup screen, another for double taps to close. In the days before, I would write like this:

This is the version with AnnoPref:

As you can see, we save 11 lines of code for these two fields. For accessing, just call:

The @Preference class and fields have some more configurations for customization as well as anti hack.

The first @Preference property I would like to mention here is prefix. This String value will apply the prefix for each field key name in the preference file. Although we don’t need to care about the key-value level, this helps us avoid naming same key for two fields in multiple preference classes. Default value of prefix is empty string (annotation doesn’t allow us to use null value).

If you feel hard in naming a prefix, just apply true to autoPrefix of the annotation @Preference. When turning this value true, the preprocessor will use the package name and class name for the prefix. The priority of autoPrefix is lower than the prefix, therefore, if prefix is not empty, the prefix value will be applied no matter what the autoPrefix is.

The third property of @Preferenceis antiHack. This will hash the key of preference fields into MD5 and Base64. This makes the keys harder to read, not exactly a real way of anti hacking, but it’s worth to give it a try. antiHack is turn off by default.

The last property of @Preferencegive us a way to define the way we access the preference: SINGLETON or STATIC functions. If we set type to SINGLETON (enum), the instance object of the preference class will be created and the getInstance() as well. The default of type is STATIC.

There are two annotations for fields, one helps us customize the key name of fields, the other give us a way to ignore a field. To customize the field key name, we use @Field(name="custom-key"). And @Ignore for the last feature. When a field name is set, it will be the parameter of the hash function if the antiHack is turned on.

Currently, the AnnoPref supports the same supported types of SharedPreferences class: boolean, int, long, float, String. Moreover, we can also store list of Integer, Long, Float, String as well as set of Integer, Long, Float, String. Actually, the list will be serialized to String before put into preference. The same thing happens to the set of Integer, Long, Float, String.

Document and code you can grab on GitHub

--

--