gpt4 book ai didi

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

转载 作者:塔克拉玛干 更新时间:2023-11-03 01:14:53 25 4
gpt4 key购买 nike

我有:

API,返回 JSON 格式的数据列表。

我的目标:

通过Retrofit+RxJava获取这些数据。

我的问题:

我只需要一个网络请求,如果屏幕在完成之前旋转,我不想开始新的请求。我还需要能够从 API 刷新数据。

我是如何解决的:

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

第二 - 完全重新创建 Retrofit 对象 (1)、retrofit-interface 的实例 (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。它从 Observable 接收 onErroronNextRetrofit 创建。 Fragment 订阅 BehaviorSubject 并接收其最后一个带有数据或错误的事件。当我需要刷新数据时,我重新创建BehaviorSubject,重新订阅RetrofitObservable来接收数据或单例中的错误并重新在 fragment 中订阅 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 onError(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;
}
}

fragment :

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 onError(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);
}
}

关于java - 如何重新创建或重置缓存的 Observable,与 Retrofit 一起使用以获取新数据?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38173653/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com