帥氣的使用SharedPreferences(含RxJava版)

背景

SharedPreferences是Android上一個輕量級的存儲類,用來保存應用
的一些常用配置渠缕。
但是使用起來還是比較繁瑣的,尤其當app比較大耿导,SharedPreferences文件以及需要保存的屬性較多時橘蜜,操作和維護起來很麻煩园蝠,經常在存取值的時候思考應該取哪個對應的Key值唆姐。

換種思路狡门,我要每一個SharedPreferences文件對應一個Java實體類瑟押,存取的時候秘噪,像操作實體類一樣操作SharedPreferences,像下面這樣:

@Spf
public class User {
    long token;

    String name;

    String mobile;

    Boolean first;
}

鏈式使用:

  Spf_User mSpfUser = Spf_User.create(this);

  // 單數(shù)據(jù) edit
  mSpfUser.name().put("name");
  String name = mSpfUser.name().get();
  String mobile = mSpfUser.name().get("defaultValue");

  // 清理Preferences
  mSpfUser.clear();

  // name 是否存在
  boolean exists = mSpfUser.name().exists();

  // 多數(shù)據(jù) edit
  mSpfUser.edit()
          .id()
          .put(124)
          .name()
          .put("name")
          .mobile()
          .remove()
          .apply();
// 也可以使用commit()提交勉耀,返回boolean類型

這樣的話指煎,操作、維護工作將大大減少便斥,當然這也是完全可以實現(xiàn)的至壤!

實現(xiàn)思路

下面只以 String name = mSpfUser.name().get() 為例分析:
反推代碼,可以想象Spf_User應該是這樣的:

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

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

    ......
}

對于StringSpfField枢纠,應該包含get()方法的實現(xiàn)像街,即:

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);
    }
    
    ......
}

這樣最基本的操作單數(shù)據(jù)是不是就完成了?晋渺!
對于存取镰绎、清除、判斷是否存在等操作也大同小異木西,多數(shù)據(jù)的操作稍微復雜畴栖,但原理也一樣,有興趣可以查看文章結尾的源碼八千。

當然如果我們對每一個SharedPreferences對象都自己手動去實現(xiàn)豈不是也挺繁瑣的吗讶,所以我用了@Spf注解燎猛,不用緊張,是編譯時注解照皆,0反射重绷,完全不會影響性能。這里不多做介紹膜毁,文章結尾源碼里都有昭卓。

引用

我將項目發(fā)布到了JCenter上,有需要的童鞋可以直接使用:

project的gradle.build里添加:

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

app的gradle.build里添加:

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

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

使用介紹

1瘟滨、像實體類一樣創(chuàng)建SharedPreferences對象XXX(參照上面 圖1代碼)葬凳,僅定義屬性即可,無須定義方法室奏,在類上使用@Spf注解;
2劲装、編譯項目胧沫;
3、編譯后生成Spf_XXX占业,使用Spf_XXX.create(Context context)創(chuàng)建實例绒怨;
4、參照上面 圖2代碼 使用谦疾。

注:
關于除String/int/boolean/long/float類型之外的屬性南蹂,可以使用Gson轉換成Json(String類型)存入,取出時再通過Gson轉成對應對象念恍。

Rx版

注:
Rx版編譯生成的文件六剥,以RxSpf_開頭!

Rx版除了具有普通版全部方法外峰伙,增加了2個方法:

asObservable():將取出的數(shù)據(jù)轉化為Observable
例如:

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():轉化為Action1疗疟,可以快速存儲數(shù)據(jù)
例如:

// 如果你使用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(),"保存成功",Toast.LENGTH_SHORT).show();
            }
        })
        .subscribe(RxSpf_User.create(context).name().asAction());
Rx版引用

project的gradle.build里添加:

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

app的gradle.build里添加:

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

dependencies {
    // 你的RxJava版本
    compile 'io.reactivex:rxjava:x.x.x'

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

源碼

GitHub地址
Rx版GitHub地址

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市瞳氓,隨后出現(xiàn)的幾起案子策彤,更是在濱河造成了極大的恐慌,老刑警劉巖匣摘,帶你破解...
    沈念sama閱讀 216,470評論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件店诗,死亡現(xiàn)場離奇詭異,居然都是意外死亡音榜,警方通過查閱死者的電腦和手機庞瘸,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,393評論 3 392
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來赠叼,“玉大人恕洲,你說我怎么就攤上這事塔橡。” “怎么了霜第?”我有些...
    開封第一講書人閱讀 162,577評論 0 353
  • 文/不壞的土叔 我叫張陵葛家,是天一觀的道長。 經常有香客問我泌类,道長癞谒,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,176評論 1 292
  • 正文 為了忘掉前任刃榨,我火速辦了婚禮弹砚,結果婚禮上,老公的妹妹穿的比我還像新娘枢希。我一直安慰自己桌吃,他們只是感情好,可當我...
    茶點故事閱讀 67,189評論 6 388
  • 文/花漫 我一把揭開白布苞轿。 她就那樣靜靜地躺著茅诱,像睡著了一般。 火紅的嫁衣襯著肌膚如雪搬卒。 梳的紋絲不亂的頭發(fā)上瑟俭,一...
    開封第一講書人閱讀 51,155評論 1 299
  • 那天,我揣著相機與錄音契邀,去河邊找鬼摆寄。 笑死,一個胖子當著我的面吹牛坯门,可吹牛的內容都是我干的微饥。 我是一名探鬼主播,決...
    沈念sama閱讀 40,041評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼古戴,長吁一口氣:“原來是場噩夢啊……” “哼畜号!你這毒婦竟也來了?” 一聲冷哼從身側響起允瞧,我...
    開封第一講書人閱讀 38,903評論 0 274
  • 序言:老撾萬榮一對情侶失蹤简软,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后述暂,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體痹升,經...
    沈念sama閱讀 45,319評論 1 310
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 37,539評論 2 332
  • 正文 我和宋清朗相戀三年畦韭,在試婚紗的時候發(fā)現(xiàn)自己被綠了疼蛾。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,703評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡艺配,死狀恐怖察郁,靈堂內的尸體忽然破棺而出衍慎,到底是詐尸還是另有隱情,我是刑警寧澤皮钠,帶...
    沈念sama閱讀 35,417評論 5 343
  • 正文 年R本政府宣布稳捆,位于F島的核電站,受9級特大地震影響麦轰,放射性物質發(fā)生泄漏乔夯。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,013評論 3 325
  • 文/蒙蒙 一款侵、第九天 我趴在偏房一處隱蔽的房頂上張望末荐。 院中可真熱鬧,春花似錦新锈、人聲如沸甲脏。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,664評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽块请。三九已至,卻和暖如春晾浴,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背牍白。 一陣腳步聲響...
    開封第一講書人閱讀 32,818評論 1 269
  • 我被黑心中介騙來泰國打工脊凰, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人茂腥。 一個月前我還...
    沈念sama閱讀 47,711評論 2 368
  • 正文 我出身青樓狸涌,卻偏偏與公主長得像,于是被迫代替她去往敵國和親最岗。 傳聞我的和親對象是個殘疾皇子帕胆,可洞房花燭夜當晚...
    茶點故事閱讀 44,601評論 2 353

推薦閱讀更多精彩內容