美文网首页
MVVM-DataSource

MVVM-DataSource

作者: tea也么 | 来源:发表于2019-11-18 16:32 被阅读0次

    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
      由于网络数据和数据库数据的属性可能存在差异性,所以需要通过该接口进行转换

    相关文章

      网友评论

          本文标题:MVVM-DataSource

          本文链接:https://www.haomeiwen.com/subject/qosbictx.html