MVVM-DataSource

2019-11-18  本文已影响0人  tea也么

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中使用
mRetrofitSource.response().observe(getViewLifecycleOwner(), rp -> {
        mBinding.weather2.setText(rp.data.weather);
});
mRetrofitSource.request().setValue("天津");
mRetrofitSource.onReload(null);

常用的DataSource

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方法

上一篇下一篇

猜你喜欢

热点阅读