java – 如何重新创建或重置缓存的Observable,与Retrofit一起使用以获取新数据?

我有

API,返回JSON中的数据列表.

我的目标:

通过Retrofit RxJava获取此数据.

我的问题:

我只需要一个网络请求,如果屏幕在完成之前旋转,我不想启动新的网络请求.此外,我需要能够从API刷新数据.

我如何解决它:

首先通过Singlton解决并使用cache()缓存Observable中的数据.

第二 – 完全重建Retrofit对象(1),改造接口(2)和Observable(3)本身的实例.我尝试只做3但失败 – Observable没有重置并发出旧的缓存数据.

题:

我重建Observable的工作方式看起来很糟糕.重新创建缓存的Observable的正确/更好的方法是什么?

有我的Singlton来获取/重建Observalbe:

public class SingltonRetrofit
{
    private static RxJavaCallAdapterFactory rxAdapter = RxJavaCallAdapterFactory.createWithScheduler(Schedulers.io());

    private static Gson gson = new GsonBuilder().create();

    private static Retrofit retrofit = new Retrofit.Builder()
            .baseUrl(Const.BASE_URL)
            .addConverterFactory(GsonConverterFactory.create(gson))
            .addCallAdapterFactory(rxAdapter)
            .build();

    private static GetModels apiService = retrofit.create(GetModels.class);
    private static Observable<ArrayList<Model>> observableModelsList;

    public static void reset()
    {
        retrofit = new Retrofit.Builder()
                .baseUrl(Const.BASE_URL)
                .addConverterFactory(GsonConverterFactory.create(gson))
                .addCallAdapterFactory(rxAdapter)
                .build();
        apiService = retrofit.create(GetModels.class);
        observableModelsList = null;
    }

    public static Observable<ArrayList<Model>> getModelsObservable()
    {
        if (observableModelsList == null)
        {
            observableModelsList = apiService.getModelsList().cache();
        }
        return observableModelsList;
    }
}

附:

同样的问题用俄语:Как правильно пересоздать закэшированный Observable используемый вместе с Retrofit?

解决方法:

最后我解决了这个问题:

我在singlton中创建BehaviorSubject.它从Obtrable接收onError或onNext,它由Retrofit创建. Fragment订阅BehaviorSubject并接收带有数据或错误的最后一个事件.当我需要刷新数据时,我重新创建BehaviorSubject,重新订阅Retrofit的Observable以在singlton中接收数据或错误并重新订阅片段中的BehaviorSubject.

public class SingltonRetrofitNew
{
    private static RxJavaCallAdapterFactory rxAdapter = RxJavaCallAdapterFactory.createWithScheduler(Schedulers.io());

    private static Gson gson = new GsonBuilder().create();

    private static Retrofit retrofit = new Retrofit.Builder()
            .baseUrl(Const.BASE_URL)
            .addConverterFactory(GsonConverterFactory.create(gson))
            .addCallAdapterFactory(rxAdapter)
            .build();

    private static GetModels apiService = retrofit.create(GetModels.class);

    private static BehaviorSubject<ArrayList<Model>> observableModelsList;
    private static Observable<ArrayList<Model>> observable = apiService.getModelsList();
    private static Subscription subscription;

    private SingltonRetrofitNew()
    {
    }

    public static void resetobservable()
    {
        observableModelsList = BehaviorSubject.create();

        if (subscription != null && !subscription.isUnsubscribed())
        {
            subscription.unsubscribe();
        }
        subscription = observable.subscribe(new Subscriber<ArrayList<Model>>()
        {
            @Override
            public void onCompleted()
            {
                //do nothing
            }

            @Override
            public void one rror(Throwable e)
            {
                observableModelsList.onError(e);
            }

            @Override
            public void onNext(ArrayList<Model> hotels)
            {
                observableModelsList.onNext(hotels);
            }
        });
    }


    public static Observable<ArrayList<Model>> getModelsObservable()
    {
        if (observableModelsList == null)
        {
            resetobservable();
        }
        return observableModelsList;
    }
}

分段:

public class FragmentsList extends Fragment
{
    private static final String TAG = FragmentList.class.getSimpleName();
    private Subscription subscription;
    private RecyclerView recyclerView;
    private ArrayList<Hotel> models = new ArrayList<>();
    private boolean isLoading;

    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState)
    {
        View v = inflater.inflate(R.layout.fragment, container, false);
        //init views
        recyclerView = (RecyclerView) v.findViewById(R.id.recycler);
        if (savedInstanceState != null)
        {
            models = savedInstanceState.getParcelableArrayList(Const.KEY_MODELS);
            isLoading = savedInstanceState.getBoolean(Const.KEY_IS_LOADING);
        }

        if (models.size() == 0 || isLoading)
        {
            getModelsList();
        }
        //Todo show saved data if is

        return v;
    }

    @Override
    public void onDestroy()
    {
        super.onDestroy();
        if (subscription != null && !subscription.isUnsubscribed())
        {
            subscription.unsubscribe();
        }
    }

    private void getModelsList()
    {
        if (subscription != null && !subscription.isUnsubscribed())
        {
            subscription.unsubscribe();
        }
        subscription = SingltonRetrofitNew.getModelsObservable().
                subscribeOn(Schedulers.io()).
                observeOn(AndroidSchedulers.mainThread()).
                subscribe(new Subscriber<ArrayList<Hotel>>()
                {
                    @Override
                    public void onCompleted()
                    {
                        Log.d(TAG, "onCompleted");
                    }

                    @Override
                    public void one rror(Throwable e)
                    {
                        Log.d(TAG, "onError", e);
                        Snackbar.make(recyclerView, R.string.connection_error, Snackbar.LENGTH_SHORT)
                                .setAction(R.string.try_again, new View.OnClickListener()
                                {
                                    @Override
                                    public void onClick(View v)
                                    {
                                        SingltonRetrofitNew.reset();
                                        getModelsList();
                                    }
                                })
                                .show();
                    }

                    @Override
                    public void onNext(ArrayList<Hotel> newModels)
                    {
                        models.clear();
                        models.addAll(newModels);
                        //Todo show data
                    }
                });
    }

    @Override
    public void onSaveInstanceState(Bundle outState)
    {
        super.onSaveInstanceState(outState);
        outState.putParcelableArrayList(Const.KEY_MODELS, models);
        outState.putBoolean(Const.KEY_IS_LOADING, isLoading);
    }
}

相关文章

Android性能优化——之控件的优化 前面讲了图像的优化,接下...
前言 上一篇已经讲了如何实现textView中粗字体效果,里面主要...
最近项目重构,涉及到了数据库和文件下载,发现GreenDao这个...
WebView加载页面的两种方式 一、加载网络页面 加载网络页面,...
给APP全局设置字体主要分为两个方面来介绍 一、给原生界面设...
前言 最近UI大牛出了一版新的效果图,按照IOS的效果做的,页...