Handsome use of SharedPreferences (including RxJava version)

background

SharedPreferences is a lightweight storage class on Android for saving applications
Some common configurations.
However, it is cumbersome to use, especially when the app is large, the SharedPreferences file, and more attributes need to be saved, which can be cumbersome to operate and maintain, often thinking about which Key value to take when accessing the value.

In a different way, I want each SharedPreferences file to correspond to a Java entity class, which is accessed by manipulating SharedPreferences like an entity class, like the following:

@Spf
public class User {
    long token;

    String name;

    String mobile;

    Boolean first;
}

Chain use:

  Spf_User mSpfUser = Spf_User.create(this);

  // Single data edit
  mSpfUser.name().put("name");
  String name = mSpfUser.name().get();
  String mobile = mSpfUser.name().get("defaultValue");

  // Clean up Preferences
  mSpfUser.clear();

  // Does name exist
  boolean exists = mSpfUser.name().exists();

  // Multidata edit
  mSpfUser.edit()
          .id()
          .put(124)
          .name()
          .put("name")
          .mobile()
          .remove()
          .apply();
// commit() can also be used to submit, returning boolean type

In this way, the operation and maintenance work will be greatly reduced, of course, this is also fully possible!

Ideas for implementation

Only String name = mSpfUser.name().get() is an example analyzed below:
By pushing back the code, you can imagine Spf_User should look like this:

public class Spf_User ...{
    ......

    public StringSpfField name() {
        return new StringSpfField(sharedPreferences,"name");
    }

    ......
}

For StringSpfField, you should include an implementation of the get() method:

public class StringSpfField ... {
    public StringSpfField(SharedPreferences sharedPreferences, String key) {
        super(sharedPreferences, key);
    }
    @Override
    public String get(String defaultValue) {
        if (defaultValue == null) {
            defaultValue = "";
        }
        return _sharedPreferences.getString(_key, defaultValue);
    }

    ......
}

Is this the most basic operation sheet data complete?!?
Access, cleanup, and judgment of existence are also very similar. Multiple data operations are slightly more complex, but they work in the same way and are interesting to see the source code at the end of the article.

Of course, it would not be cumbersome if we were to manually implement each SharedPreferences object by ourselves, so I used the @Spf annotation, not to stress, compile-time annotation, 0 reflection, and no performance impact at all.There are no more descriptions here, and the source code at the end of the article is included.

Quote

I posted the project on JCenter, where children's shoes can be used directly if they need them:

The gradle.build for project adds:

buildscript {
   dependencies {
       classpath 'com.neenbedankt.gradle.plugins:android-apt:1.8' 
   }
}

Add in gradle.build of app:

apply plugin: 'com.neenbedankt.android-apt'

dependencies {
    compile 'me.yokeyword.smartsharedpreferences:api:1.0.0'
    apt 'me.yokeyword.smartsharedpreferences:compiler:1.0.0'
}

Introduction to Use

1. Create the SharedPreferences object XXX like an entity class (refer to the code in Figure 1 above) by defining attributes only, without defining methods, and using the @Spf annotation on the class;
2. Compile the project;
3. Spf_XXX is generated after compilation and an instance is created using Spf_XXX.create(Context context);
4. Use the code in Figure 2 above.

Note:
For attributes other than String/int/boolean/long/float, Gson can be used to convert them to Json(String type) for storage, and Gson can be used to convert them to corresponding objects when they are removed.

Rx version

Note:
The Rx version compiles the generated file, starting with RxSpf_

The Rx version adds two methods in addition to all the methods available in the normal version:

asObservable(): Convert the extracted data into Observable
For example:

RxSpf_User.create(context)
        .name().asObservable()
        .subscribeOn(Schedulers.io())
        .map(new Func1<String, String>() {
            @Override
            public String call(String s) {
                return "rx" + s;
            }
        })
        .observeOn(AndroidSchedulers.mainThread())
        .subscribe(new Action1<String>() {
            @Override
            public void call(String s) {
                mTvShow.setText("name:  " + s);
            }
        })

asAction(): Converted to Action1 for fast data storage
For example:

// If you use RxBinding
RxView.clicks(mBtnSave)
        .map(new Func1<Void, String>() {
            @Override
            public String call(Void aVoid) {
                return mEtName.getText().toString();
            }
        })
        .doOnNext(new Action1<String>() {
            @Override
            public void call(String s) {
                Toast.makeText(getApplicationContext(),"Save Successfully",Toast.LENGTH_SHORT).show();
            }
        })
        .subscribe(RxSpf_User.create(context).name().asAction());
Rx version reference

The gradle.build for project adds:

buildscript {
   dependencies {
       classpath 'com.neenbedankt.gradle.plugins:android-apt:1.8' 
   }
}

Add in gradle.build of app:

apply plugin: 'com.neenbedankt.android-apt'

dependencies {
    // Your RxJava version
    compile 'io.reactivex:rxjava:x.x.x'

    compile 'me.yokeyword.rxsmartsharedpreferences:api:1.0.0'
    apt 'me.yokeyword.rxsmartsharedpreferences:compiler:1.0.0'
}

Source code

GitHub address
Rx GitHub Address

From: https://www.jianshu.com/p/3da7ec4ee6f6

Keywords: Gradle Android Mobile github

Added by Chantal on Sun, 19 May 2019 17:47:38 +0300