MVVM-DataSource

MVVM-导入配置

简介

熟悉谷歌arch框架的同学都知道,arch中mvvm思想主要依靠LiveData来作为数据源驱动界面,这里的DataSource提供了request和response两个LiveData,response用于驱动界面改变,request用于设置请求参数。
数据请求和响应实现了分离:

// old
getCall(request, response->{
  view.onChange();
})

// now
// 界面只需要设置一个唯一数据源
response().observer(this,response->{
  view.onChange();
})
// 数据请求可以设置在任何地方
click1(v->{
 request().setValue(request1);
})
click2(v->{
 request().setValue(request2);
})

DataSorece全局唯一性:
每一个DataSorece全局单例,所有的界面都依赖同一个数据源,也就不再会出现数据不同步的问题了,从而达到牵一发动全身的效果。DataSorece实现了如同EventBus的效果,但又优于EventBus,因为避免了EventBus的不易追溯和缺乏 Lifecycle 的加持等缺点。

使用介绍

  1. 根据所需实现DataSource,下面有具体介绍
  2. 在ViewModel中通过@Source声明DataSource,ViewModel需要继承BaseViewModel
public class ArchViewModel extends BaseViewModel {
    @Source
    public WeatherRetrofitSource mRetrofitSource;
    public ArchViewModel(@NonNull Application application) {
        super(application);
    }
}
  1. 在ViewController中使用
  • 获取响应数据,驱动UI
mRetrofitSource.response().observe(getViewLifecycleOwner(), rp -> {
        mBinding.weather2.setText(rp.data.weather);
});
  • 发起请求
mRetrofitSource.request().setValue("天津");
  • 重新加载,会根据上一次的的请求参数再次请求数据
mRetrofitSource.onReload(null);

常用的DataSource

  • IRetrofitDataSource
  • IRoomDataSource
  • IRetrofitAndRoomDataSource

IRetrofitDataSource只访问网络,IRoomDataSource只访问数据库,IRetrofitAndRoomDataSource访问网络和数据库

IRetrofitDataSource

public class WeatherSource extends IRetrofitDataSource<String, CurWeather> {
    @NonNull
    @Override
    public Call<CurWeather> getCall(String city) {
        return WebService.getInstance().getWeather(city);
    }
}
public interface IWebService {
    @GET("http://www.mxnzp.com/api/weather/current/{city}")
    Call<CurWeather> getWeather(@Path("city") String city);
}

在WebService中配置好网络访问的接口,然后直接实现IRetrofitDataSource的getCall的方法即可

IRoomDataSource

public class WeatherRoomSource extends IRoomDataSource<String, WeatherEntity> {
    private WeatherDao mDao;
    public WeatherRoomSource(@NonNull Application application) {
        super(application);
        mDao = DBManager.getInstance(mApplication).mDatabase.mWeatherDao();
    }


    @NonNull
    @Override
    public LiveData<WeatherEntity> query(@Nullable String param) {
        return mDao.query(param);
    }

    @Override
    public void insert(@NonNull WeatherEntity weatherEntity) {
        mDao.insert(weatherEntity);
    }

    @Override
    public void delete(@NonNull WeatherEntity weatherEntity) {
        mDao.delete(weatherEntity);
    }

    @Override
    public void update(@NonNull WeatherEntity weatherEntity) {
        mDao.update(weatherEntity);
    }
}
@Dao
public interface WeatherDao {
    @Query("select * from weatherentity where address=:address")
    LiveData<WeatherEntity> query(String address);

    @Insert(onConflict = OnConflictStrategy.REPLACE)
    void insert(WeatherEntity... entity);

    @Delete
    void delete(WeatherEntity... entity);

    @Update
    void update(WeatherEntity entity);
}

RoomSource需要实现增删改查四个接口

IRetrofitAndRoomDataSource

public class WeatherMixDataSource extends IRetrofitAndRoomDataSource<String, CurWeather,
        WeatherEntity> {
    private WeatherDao mDao;

    public WeatherMixDataSource(@NonNull Application application) {
        super(application);
        mDao = DBManager.getInstance(mApplication).mDatabase.mWeatherDao();
    }

    @NonNull
    @Override
    public Call<CurWeather> getCall(@Nullable String request) {
        return WebService.getInstance().getWeather(request);
    }

    @Override
    protected boolean isUpdateFromNet(@Nullable String request) {
        return true;
    }

    @NonNull
    @Override
    protected WeatherEntity transformNetToDbData(@NonNull CurWeather netData) {
        ...
        ...
        return entity;
    }

    @NonNull
    @Override
    public LiveData<WeatherEntity> query(@Nullable String param) {
        return mDao.query(param);
    }

    @Override
    public void insert(@NonNull WeatherEntity entity) {
        mDao.insert(entity);
    }

    @Override
    public void delete(@NonNull WeatherEntity entity) {
        mDao.delete(entity);
    }

    @Override
    public void update(@NonNull WeatherEntity entity) {
        mDao.update(entity);
    }
}

IRetrofitAndRoomDataSource的实现原理就是每次查询会首先访问数据库数据,然后根据isUpdateFromNet方法判断是否访问网络更新最新数据,如果更新则会同步到数据库中,并把数据反馈到界面上
IRetrofitAndRoomDataSource除了要实现网络接口和数据库增删改查的接口,还需要实现isUpdateFromNet和transformNetToDbData方法

  • isUpdateFromNet
    判断是否从网络更新数据到数据库,这个地方可以设置一个时间段来做更新数据的依据,从而避免频繁访问网络相同资源,造成资源浪费
  • transformNetToDbData
    由于网络数据和数据库数据的属性可能存在差异性,所以需要通过该接口进行转换
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 218,451评论 6 506
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,172评论 3 394
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 164,782评论 0 354
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,709评论 1 294
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,733评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,578评论 1 305
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,320评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,241评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,686评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,878评论 3 336
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,992评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,715评论 5 346
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,336评论 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,912评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,040评论 1 270
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,173评论 3 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,947评论 2 355