做缓存

作者: 资本家大恶人 | 来源:发表于2020-08-26 19:46 被阅读0次

思路

  • 重写MVP Repoistory进行读取缓存添加缓存方法
  • 单例通过是只创建一个model对象
  • 将数据存储到对象中,通过HashMap()通过(key,value)的形式

==[读数据]==

  • 判断是否是第一次请求
    (刷新和加载更多是都是重新从网络拿取数据)
    1.从内存读取数据
    2.从sdcard读取数据
    3.如果都没有数据默认从网络获取数据

==[存数据]==

实现Consumer接口
1.得到保存的Key值
2.保存到缓存
3.保存到sdcard

问题

recycle出现条目重复绑定

解决办法

将数据缓存新的集合


public class RecommondRepository extends BaseRepository {
    private static final String CACHE_FILE_NAME_PREFIX = "version_code";
    private static RecommondRepository mInstance;
    private HashMap<String, RecommendData> mMemoryData = new HashMap<>();

    /**
     *
     * @return
     * 单例是的只有一个model对象
     */
    public static RecommondRepository getInstance() {
//        判断对象是否创建
        if (mInstance == null) {
//            在此处创建线程索让其他线程减少等待时间
            synchronized (RecommondRepository.class) {
//                如果线程1拿到锁对象未创建完成,线程2拿到锁创建完对象线程1继续创建此时对象已经通过线程2实例化所以进行二次判空
                if (mInstance == null) {
//                    创建对象
                    mInstance = new RecommondRepository();

                }
            }
        }

        return mInstance;
    }

    @Override
    public <T> void doRequest(LifecycleProvider lifecycleProvider, MvpRequest<T> request, IBaseCallBack<T> callBack) {
        /*取数据*/
//        不调用父类的方法,重写子类
//        super.doRequest(lifecycleProvider, request, callBack);
//        得到栏目ID
        String columnId = request.getParams().get(Constract.RequestKey.KEY_COLUMN_ID).toString();

        switch (request.getRequestType()) {

//            case加入括号{}可以重复创建变量局部变量只能在方法里有效
/**
 * 默认都是第一次请求
 * 刷新和加载更多都不需要读取缓存数据
 */
            case FIRST: {
//                step1.先从内从存查找直接传入P层
                MvpResponse response = getFromMemory(columnId);
                if (response != null) {
                    callBack.onResult(response);
                    return;

                }
//             step2.如果内存没有直接从sdcard读取


                /*
                 *Observable 内置线程池节省系统开销
                 * scared都为耗时操作为 */
                Observable.create(new ObservableOnSubscribe<MvpResponse>() {
                    @Override
                    public void subscribe(@NonNull ObservableEmitter<MvpResponse> emitter) throws Throwable {
                        MvpResponse fromSdCard = getFromSdCard(columnId);
                        if (fromSdCard != null) {
                            emitter.onNext(fromSdCard);
                            emitter.onComplete();
                        } else {
                            emitter.onError(new NullPointerException("sdcard no data"));
                        }
                    }
                })
                        .subscribeOn(Schedulers.io())
                        .observeOn(AndroidSchedulers.mainThread())
                        .subscribe(new Consumer<MvpResponse>() {
                            @Override
                            public void accept(MvpResponse mvpResponse) throws Throwable {
                                callBack.onResult(mvpResponse);
                            }
                        }, new Consumer<Throwable>() {
                            @Override
                            public void accept(Throwable throwable) throws Throwable {
                                doRequest(lifecycleProvider, request, callBack, new CacheTask<>(request));
                            }
                        });

                break;
            }
            default:{
//                从服务请求

                doRequest(lifecycleProvider,request,callBack,new CacheTask<>(request));
            }
        }

    }
//  读取内存数据
    private MvpResponse getFromMemory(String key) {
//        看内存是否有该数据
        RecommendData data = mMemoryData.get(key);
        if (data != null) {
//            设置数据
            MvpResponse<RecommendData> response = new MvpResponse<>();
            return response.setData(data).setCode(1).setRequestType(RequestType.FIRST).setType(ResponseType.MEMORY);
        }
        return null;
    }

    /**
     * @param key
     * @return 从sd卡读取文件
     */
    private MvpResponse getFromSdCard(String key) {
//        从内存卡读取数据
        RecommendData data = MvpDataFileCacheUtils.getencryptedDataFromFile(getCacheDataSdcardFile(key), RecommendData.class);
        if (data != null) {
            MvpResponse<RecommendData> response = new MvpResponse<>();
            return response.setCode(1).setData(data).setType(ResponseType.SDCARD);
        }
        return null;
    }

    /**
     * @param columnId
     * @return 创建手机文件
     */
//    找到文件
    private File getCacheDataSdcardFile(String columnId) {
        return new File(MvpManager.getExternalCacheDir(), CACHE_FILE_NAME_PREFIX + columnId);
    }

//  缓存数据
    private class CacheTask<T> implements Consumer<MvpResponse<T>> {//实现做缓存接口

        private MvpRequest request;

        CacheTask(MvpRequest request) {
            this.request = request;
        }

        @SuppressWarnings("ALL")
        @Override
        public void accept(MvpResponse<T> mvpResponse) throws Throwable {
//            得到保存的Key值
            String key = request.getParams().get(Constract.RequestKey.KEY_COLUMN_ID).toString();
            saveToMemory((MvpResponse<RecommendData>) mvpResponse, request.getRequestType(), key);
            saveToSdcard((MvpResponse<RecommendData>) mvpResponse, key);
        }
//         保存到card
        private void saveToSdcard(MvpResponse<RecommendData> mvpResponse, String key) {

        }
//      保存到内存
        private void saveToMemory(MvpResponse<RecommendData> mvpResponse, RequestType requestType, String key) {
            if (requestType != RequestType.LOAD_MORE){//不是加载更多
                mMemoryData.clear();//将内存设置空
                RecommendData recommendData = new RecommendData();//创建空对象开辟内存
                RecommendData serverData = mvpResponse.getData();//从网络获取data
//                设置数据
                recommendData.setAlbumId(serverData.getAlbumId());
                recommendData.setAlbumNews(serverData.getAlbumNews());
                recommendData.setAlbumTitle(serverData.getAlbumTitle());
                recommendData.setBannerList(serverData.getBannerList());
                recommendData.setFlashId(serverData.getFlashId());
                recommendData.setFlashNews(serverData.getFlashNews());
                recommendData.setMore(serverData.getMore());
                recommendData.setPointTime(serverData.getPointTime());
                recommendData.setStart(serverData.getStart());
                recommendData.setNews(new ArrayList<>(serverData.getNews()));
//                缓存到集合
                mMemoryData.put(key,recommendData);
            }else {
                RecommendData cacheData = mMemoryData.get(key);//获取缓存加入数据

                RecommendData serverData = mvpResponse.getData();//获取网络数据
//                如果网络数据和缓存数据都不为空
                if(cacheData != null && serverData != null){
//                    所有数据只有新闻数据需要实施gen新
                    cacheData.setStart(serverData.getStart());
                    cacheData.setNumber(serverData.getNumber());
                    cacheData.setPointTime(serverData.getPointTime());
                    cacheData.setMore(serverData.getMore());
                    cacheData.getNews().addAll(serverData.getNews());
                }
            }
        }
    }

}

相关文章