Skip to content


Switch branches/tags

Latest commit


Git stats


Failed to load latest commit information.
Latest commit message
Commit time

Development in this repository is stopped. Future development continues on



PSync is a gradle plugin for android projects to generate Java representations of xml preferences.

Some applications have a lot of preferences, each their own keys, default values, and more. These tend to be stored in xml files (under res/xml), and don't have any programmatic linking of their values. The result? You have to manually keep these values in sync with your Java code. Yikes!

We got tired of dealing with this at Flipboard. Our preference class ended up with 200+ lines of boilerplate at the top that we manually had to keep in sync, and it was becoming a nuisance. PSync was developed to resolve this, and we hope it helps you too!


Apply the PSync plugin to your module below your android plugin application

buildscript {
  repositories {
    maven {
      url ""
  dependencies {
    classpath ""

apply plugin: '' // Can be library too
apply plugin: 'com.flipboard.psync'

The PSync plugin will create a generating task for each of your variants, and will generate a file at compilation that will be included in your classpath. This process is purposefully very similar to how the file works. The default name for this class is, but you can configure it to be another name if you wish.

Speaking of configuration, here's how you can configure PSync to work for you.

psync {
    className = "MyClassName"
    includesPattern = "**/xml/<mypatternforfiles>.xml"
    packageName = "com.example.myapp"
    generateRx = true

Let's take a look at each:

className is the name of the class. The default is just P.

includesPattern is an ant-style includes pattern for preference xml files in your resources. This is useful if you have a lot of other xml files and want to save the plugin a little work by filtering out non-pref ones. In Flipboard, all our preference files are prefixed with prefs_, so our includes pattern would be **/xml/prefs_*.xml. The default is to parse all xml files in xml resource directories.

packageName is what you want to use for the package name of the generated resource classes. The default behavior of the plugin is to retrieve this from your variant's applicationId value. NOTE: Library projects MUST specify this, since they don't have applicationId values.

generateRx is a flag indicating whether or not you want code generated for usage with Rx-Preferences, which is a great library that adds reactive bindings around SharedPreferences


Using the generated file is easy, and should feel very familiar to how you would use

Each preference is represented by a static inner class, with a key field, a defaultResId field if it's a resource, and some or all of following functions:

  • defaultValue() for retrieving the default value
  • get() for retrieving the current stored value
  • put() for storing a new value
    • NOTE: This returns an Editor instance, where you much apply or commit the change(s)
  • rx() for retrieving an appropriate Rx-Preferences instance of Preference, if you enabled generateRx above.

These functions are generated when appropriate. If no default value or resource reference is specified, the plugin will not try to guess the type and generate code for it.

First thing's first: Initialize your file in your Application's onCreate() method.

public class MyApp extends Application {

    public void onCreate() {

        // Required

        // Optional
        // By default, it will initialize its internal SharedPreferences instance to the system default
        // You can change its used instance at any time


Let's take a look at an example. The following xml preference:


Becomes this Java code:

public final class P {
    public static final class showImages {
        public static final String key = "show_images";

        public static final boolean defaultValue() {
            return true;

        public static final boolean get() {
            return PREFERENCES.getBoolean(key, defaultValue());

        public static final SharedPreferences.Editor put(final boolean val) {
            return PREFERENCES.edit().putBoolean(key, val);

        public static final Preference<Boolean> rx() {
            return RX_SHARED_PREFERENCES.getBoolean(key);

You can now reference this in code like so:

String theKey = P.showImages.key;
boolean theDefault = P.showImages.defaultValue();
boolean current = P.showImages.get();

// If you use Rx-Preferences

Nice and simple right? Note that the entry block's name will be a camelCaseLower conversion of the key.

Let's look at a resource example now. The following preference:


Becomes the following Java code:

public final class P {
    public static final class serverUrl {
        public static final String key = "server_url";
        public static final int defaultResId = R.string.server_url;

        public static final String defaultValue() {
            return RESOURCES.getString(defaultResId);

        public static final String get() {
            return PREFERENCES.getString(key, defaultValue());

        public static final SharedPreferences.Editor put(final String val) {
            return PREFERENCES.edit().putString(key, val);

        public static final Preference<String> rx() {
            return RX_SHARED_PREFERENCES.getString(key);

Notice that resources are handled a little differently. This is intentional, and for convenience. Using this code now looks like this:

String theKey = P.serverUrl.key;
int theResId = P.serverUrl.defaultResId;
String theDefault = P.serverUrl.defaultValue();
String currentValue = P.serverUrl.get();

// If you use Rx-Preferences

Easy peasy. Enjoy!


We welcome pull requests for bug fixes, new features, and improvements to PSync. Contributors to PSync repository must accept Flipboard's Apache-style Individual Contributor License Agreement (CLA) before any changes can be merged.


A gradle plugin for android projects to generate Java representations of xml preferences.







No packages published