SimplePrefs

Additional

Language
Java
Version
N/A
Created
Jun 2, 2015
Updated
Jul 3, 2015 (Retired)
Owner
Dimitry (noties)
Contributor
Dimitry (noties)
1
Activity
Badge
Generate
Download
Source code

SimplePrefs

SimplePrefs is an Android library that helps working with SharedPreferences.

Core

The core module minimizes the ammount of code when working with SharedPreferences by overloading methods.

Installation

compile 'ru.noties.simpleprefs:core:x.x.x'

Example:

final SimplePref pref = new SimplePref(mContext, "some_pref");

// getters
final String someString = pref.get("string", null); // or just pref.get("string"); as long as String is the only Object supported by SimplePrefs library
final int someInt = pref.get("int", -1);
final long someLong = pref.get("long", -1L);
final float someFloat = pref.get("float", .0F);
final boolean someBool = pref.get("bool", false);

//setters
pref.set("string", null); // String
pref.set("int", 101);
pref.set("long", -1L);
pref.set("float", 15.F);
pref.set("bool", true);

When setting and getting values one should explicitly cast to desired type. For example, adding L after a decimal will create a value of type long; F will set a value to float

Sometimes there is a need to set multiple values at once (every call to set internally calls Editor.apply()), so there is a Batch helper class that helps to achive that:

pref.batch() // returns an Object of Type Batch
    .set("string", null)
    .set("int", 0)
    .set("long", 0L)
    .set("float", 33.F)
    .set("bool", false)
    .apply(); // don't forget to call apply

Data-binding

We may step further and create model objects around SharedPreferences data with support for Json serialization/deserialization

Annotations:

Processor:

 compile 'ru.noties.simpleprefs:core:x.x.x'
    provided 'ru.noties.simpleprefs:annotations:x.x.x' // we may mark dependancy as provided, because we won't be needing annotations information at runtime
    apt('ru.noties.simpleprefs:processor:x.x.x') {
        transitive = false
    }

SimplePrefs using an awesome apt tool: page

To define a custom data model we will use java annotations.

@Preference

The start defining data model we should create public, non-final, non-abstract class that extends PrefsObject and annotate it with @Preference annotation:

@Preference
public class MySharedData extends PrefsObject {
...
}

@Preference has a number of optional parameters:

@Preference(
    value = "my_super_prefs", // the name of SharedPreferences file. If left blank the class name will be used
    isSingleton = true, // if true - an object will be a singleton

    jsonLibrary = JsonLibrary.GSON, // currently only Gson is supported
    isJsonVariableStatic = true, // whether json library variable should be static (no much sence for a singleton)
    catchJsonExceptions = true, // whether the code that works with json should be wrapped around try/catch

    jsonTypes = { Date.class }, // additionally we could provide out own json serialization/deserialization policies, here is the serialized class
    jsonTypeSerializers = { DateJsonSerializer.class } // and here is the serializer
)

In order to achive working fuctionality with custom json serializers, we should enumerate them in the exact order in which serialized classes are enumerated. Also, serializer class should implement both JsonSerializer<T> and JsonDeserializer<T> (in case of Gson)

If catchJsonExceptions is set to true, then you could override the PrefsObject's method in your data model class to log or do whatever you wish with the catched exception:

@Override
public void onJsonExceptionHandled(Throwable t) {
    ...
}

@Key

The next thing to define keys for your data model is the @Key annotation

@Key
private String someKeyString;

It has a number of optional parameters:

@Key(
    value = "key_name", // a name for this key, if left blank - field's name will be used
    defaultValue = "default value for this key", // default value for this key as a string, for example "null", "0", "1L", "true"
    isJson = false // indicates that this key should be treated as json. If set to true - defaultValue would not be considered
)

After keys are defined we must create public non-final getters and setters methods for all of them. The reason behind this is simple: annotation processor will generate a subclass of your model class and will use getters/setters as a data transation pipe. No fields of your data-model will be changed, thus there is no need for accessing them directly. The main and only use for object's fields is to define getters and setters.

If standart pattern of getters and setters would change in IDEA or if there is a need for custom naming, there are two annotations to help with this: @Setter and @Getter. Both have one required parameter: name of the key. It should be a real key's name: name that was passed to @Key annotation or a field's name

@Key("some_key")
String token;

@Setter("some_key")
public void noWayIWillTellWhatIDo(String value) {}

@Getter("some_key")
public String nahItsAVoidReally() {}

@OnUpdate

Additionally a data object could be notified when some value is changed. Define a method inside your data object class which takes one parameter - type of the key it listens to

@OnUpdate("some_key")
public void onSomethingInterestingHappend(String value) {
...
}

Further you could define a listener interface and call it (see a sample project for the example).

Using of Data-binding

After your data model is defined you can obtain your data object via static method PrefsObject.create():

final MyPrefsModel pref = PrefsObject.create(MyPrefsModel.class, mContext);

Annotation processor will generate a YourClassName$$SP class. If you wish you could access it directly, but I discourage you to do so.

final MyPrefsModel pref = PrefsObject.create(MyPrefsModel.class, mContext);
pref.setSomeKey(null);
final String key = pref.getSomeKey();

Note, that PrefsObject doesn't use any caching mechanism, so every call to set...() or get...() will call wrapped SimplePref.

License

  Copyright 2015 Dimitry Ivanov (mail@dimitryivanov.ru)

  Licensed under the Apache License, Version 2.0 (the "License");
  you may not use this file except in compliance with the License.
  You may obtain a copy of the License at

      http://www.apache.org/licenses/LICENSE-2.0

  Unless required by applicable law or agreed to in writing, software
  distributed under the License is distributed on an "AS IS" BASIS,
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  See the License for the specific language governing permissions and
  limitations under the License.