Silk,一個(gè)基于java bean的輕量級(jí)響應(yīng)式框架

Silk

一個(gè)基于java bean的響應(yīng)式框架

Why we need this?

假設(shè)我們有這么一個(gè)需求:
我們登陸成功之后通過服務(wù)器拿到一個(gè)useraccount對(duì)象,useraccount對(duì)象長(zhǎng)這個(gè)樣子

public class UserAccount{
  private String userName;//姓名
  private int age;//年齡
  private String userImage;//頭像

  public void setUserName(String userName){
    this.userName = userName;
  }
  
  public String getUserName(){
    return userName;
  }
  
  //后略......
}

我們會(huì)在界面上展示登陸用戶的姓名,頭像等等:

UserAccount useraccount = getUserAccount();//獲取到了useraccount對(duì)象
TextView tvName = findViewById(R.id.tv_name);
tvName.setText(useraccount.getUserName());

OK,接下來如果我們需要修改用戶的姓名,那么以往我們是這樣的:

useraccount.setUserName("mike");
//其他的工作
tvName.setText(useraccount.getUserName());
//其他的展示

這里面,我們一般是給對(duì)象set了某個(gè)值之后,再更新UI。

Now,We change

使用silk之后,現(xiàn)在我們的useraccount定義是這樣的:(就多了一個(gè)注解而已)

@RxBean
public class UserAccount{
  private String userName;//姓名
  private int age;//年齡
  private String userImage;//頭像

  public void setUserName(String userName){
    this.userName = userName;
  }
  
  public String getUserName(){
    return userName;
  }
  
  //后略......
}

我們接下來這樣展示里面的數(shù)據(jù):

TextView tvName = findViewById(R.id.tv_name);
SilkBrite<UserAccount> brite = SilkBrite.create();//初始化了一個(gè)brite
UserAccount useraccount = brite.asSilkBean(getUserAccount());//獲取useraccount對(duì)象,其實(shí)這是一個(gè)“換了包”的對(duì)象
brite.asModeObservable()
    .subscribeOn(Schedulers.io())
    .observeOn(AndroidSchedulers.mainThread())
    .subscribe(new Action1<UserAccount>() {
                    @Override
                    public void call(UserAccount info) {
                        tvName.setText(useraccount.getUserName());
                    }
                });

然后我們要修改用戶姓名了!

//你只需要做下面這件事,UI上面就會(huì)同步
useraccount.setUserName("mike");

所以,用了silk,我們就不需要每次修改了bean之后還要去同步UI。

引用

  • gradle,在你的app的build.gradle文件中引入依賴
dependencies {
    ...
    compile 'com.github.landscapeside:SilkLib:1.0'
    apt 'com.github.landscapeside:SilkComplier:0.1'
    ...
}

然后在你的app的build.gradle中應(yīng)用apt插件:

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

project的build.gradle中申明:

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

用的是jitpack倉庫,所以需要在project的build.gradle中注明

allprojects {
    repositories {
        jcenter()
        maven { url "https://jitpack.io" }
    }
}

用法

  • 如上所說,在你需要silk功能的java bean類上使用RxBean注解,然后重新構(gòu)建一下項(xiàng)目
  • 然后要新建一個(gè)SilkBrite出來SilkBrite<UserAccount> brite = SilkBrite.create();,注意,目前來說,一個(gè)brite就對(duì)應(yīng)處理一個(gè)bean對(duì)象
  • 接下來需要將原有的bean對(duì)象設(shè)置一個(gè)代理UserAccount useraccount = brite.asSilkBean(getUserAccount());
  • 上一步生成的代理對(duì)象才能真正嵌入到Silk響應(yīng)式框架之中,通過bean的setter即可觸發(fā)相應(yīng)
  • 我們需要監(jiān)聽到事件源發(fā)出的消息并作出反應(yīng)
brite.asModeObservable()
    .subscribeOn(Schedulers.io())
    .observeOn(AndroidSchedulers.mainThread())
    .subscribe(new Action1<UserAccount>() {
                    @Override
                    public void call(UserAccount info) {
                        tvName.setText(useraccount.getUserName());
                    }
                });
  • 當(dāng)然,還可以嵌套使用,比如一個(gè)Parent對(duì)象有2個(gè)Child,不管是修改Parent的屬性或者是child屬性,我們都希望能得到通知,則兩個(gè)類都標(biāo)記上RxBean注解即可
@RxBean
public class Parent{
  private String userName;//姓名
  private int age;//年齡
  private String userImage;//頭像
  private Child child1;
  private Child child2;

  public void setUserName(String userName){
    this.userName = userName;
  }
  
  public String getUserName(){
    return userName;
  }
  
  //后略......
}

@RxBean
public class Child{
  private String userName;//姓名
  private int age;//年齡
  //......
}
  • 有時(shí)候我們有這樣的需求,顯示UserAccount的nick的時(shí)候希望能加上如果為空的默認(rèn)顯示
brite.asNodeObservable("nick")
        .subscribeOn(Schedulers.io())
        .observeOn(AndroidSchedulers.mainThread())
        .map(o1 -> {
            String name = String.valueOf(o1);
            if (TextUtils.isEmpty(name)) {
                return "unknown user";
            }
            return name;
        })
        .subscribe(new Action1<String>() {
                @Override
                public void call(String name) {
                    tvName.setText(name);
                }
            });

  • 如果是要加上child的默認(rèn)顯示
brite.asNodeObservable("child1::userName")
        .subscribeOn(Schedulers.io())
        .observeOn(AndroidSchedulers.mainThread())
        .map(o1 -> {
            String name = String.valueOf(o1);
            if (TextUtils.isEmpty(name)) {
                return "unknown user";
            }
            return name;
        })
        .subscribe(new Action1<String>() {
                @Override
                public void call(String name) {
                    tvName.setText(name);
                }
            });

限制

  • 首先,一個(gè)brite就是用來處理一個(gè)bean對(duì)象,所以并不太適合列表類的應(yīng)用,當(dāng)然后續(xù)會(huì)考慮改進(jìn)
  • 而且就如Silk的開發(fā)目的一樣,它就只是為了解決基于bean的響應(yīng)式編程,如果是基于sqlite的響應(yīng)式需求,請(qǐng)移步sqlbrite

最后

感謝如下項(xiàng)目給我的指導(dǎo)和參考:

項(xiàng)目地址

https://github.com/landscapeside/Silk

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn),斷路器,智...
    卡卡羅2017閱讀 136,724評(píng)論 19 139
  • Spring Boot 參考指南 介紹 轉(zhuǎn)載自:https://www.gitbook.com/book/qbgb...
    毛宇鵬閱讀 47,290評(píng)論 6 342
  • 文章作者:Tyan博客:noahsnail.com 3.4 Dependencies A typical ente...
    SnailTyan閱讀 4,518評(píng)論 2 7
  • 1. Java基礎(chǔ)部分 基礎(chǔ)部分的順序:基本語法,類相關(guān)的語法,內(nèi)部類的語法,繼承相關(guān)的語法,異常的語法,線程的語...
    子非魚_t_閱讀 34,900評(píng)論 18 399
  • 1.馬云把員工分為野狗、小白兔和獵犬型,野狗就是沒有團(tuán)隊(duì)合作精神但有責(zé)任心的,小白兔就是老好人但沒有工作業(yè)績(jī)的,獵...
    Kayan阿嘉閱讀 510評(píng)論 0 22

友情鏈接更多精彩內(nèi)容