Android replay().autoconnect()不重播事件
我在使用Android replay().autoconnect()不重播事件,android,rx-java,rx-java2,Android,Rx Java,Rx Java2,我在使用replay().autoconnect()运算符组合时遇到一些问题。 在我提问之前,让我分享一些关于这个操作符的知识。我一直在关注这个 我所理解的是 replay()当新订户进来时,操作员可以重新发出可观察结果,而无需重新执行源可观察结果(在网络呼叫期间有帮助) autoconnect()可以将可观察对象转换为热可观察对象,这样即使所有订阅者离开后新订阅者进来,可观察对象仍将处于活动状态,并通过replay()重新发送结果。 因此,我发现replay().autoConnect()
replay().autoconnect()
运算符组合时遇到一些问题。
在我提问之前,让我分享一些关于这个操作符的知识。我一直在关注这个
我所理解的是
当新订户进来时,操作员可以重新发出可观察结果,而无需重新执行源可观察结果(在网络呼叫期间有帮助)replay()
可以将可观察对象转换为热可观察对象,这样即使所有订阅者离开后新订阅者进来,可观察对象仍将处于活动状态,并通过autoconnect()
replay()重新发送结果。
replay().autoConnect()
组合适合我的网络呼叫
在我的应用程序中,我到处都使用片段,而在BaseFragment
中,我保留了一个组合文件。在碎片生命周期中,我一直在CompositeDisposable
和onDestroyView
事件中添加我的所有一次性物品,我正在处理这些一次性物品,因为我不想在碎片不可见时听到可观察到的排放
我有一个用例,我在一个片段中进行网络调用,比如说FragmentA
,然后转到FragmentB
,而不终止FragmentA
(我正在进行片段替换)。稍后,我可以从backstack返回到FragmentA
。
当我从FragmentA
移动到FragmentB
时,显然我的观察者会被释放,但我期望的是,当我稍后回到FragmentA
时,我应该立即得到旧的网络调用结果,因为我在可观察对象上使用了replay().autoConnect()
但是这里发生了一些奇怪的事情,我可以看到旧的可观察物仍然存在,但是它没有发出任何值。
如果我更改mCompositeDisposable.dispose()
到onDestroy()
而不是onDestroyView()
它可以按预期工作
根据教程,autoconnect()即使所有观察者离开,也不会终止可观察对象
但在我的例子中,当所有的观察者离开,然后新的观察者进来时,它不会只发出,而且因为它触发了doOnsubscribe()
所以我只能在UI中看到一个无限加载对话框(因为我在doOnsubscribe
上显示loader)。我发布了一个示例代码,完全复制了我的问题
BaseFragment.java
MainActivity.java
FragmentA.java
public类FragmentA扩展了BaseFragment{
私有文本视图文本视图;
私人按钮;
私有静态最终字符串TAG=“FragmentA”;
@可空
@凌驾
创建视图时的公共视图(LayoutFlater充气机、@Nullable ViewGroup容器、@Nullable Bundle savedInstanceState){
视图=充气机。充气(R.layout.fragmenta,容器,假);
textView=(textView)view.findViewById(R.id.txt);
按钮=view.findViewById(R.id.button);
setOnClickListener(v->((MainActivity)getActivity()).replaceFragment(newfragmentB());
返回视图;
}
@凌驾
ActivityCreated上的公共无效(@Nullable Bundle savedinStateCState){
super.onActivityCreated(savedInstanceState);
DisposableObserver DisposableObserver=Repository.getStringObservable()
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.doOnNext(字符串->dismissProgress())
.doOnSubscribe(一次性->显示进度(“请稍候”))
.subscribowith(新可处置观察员){
@凌驾
public void onNext(列出字符串){
StringBuilder StringBuilder=新的StringBuilder();
for(字符串:字符串){
stringBuilder.append(字符串).append(“\n”);
}
textView.setText(stringBuilder.toString());
}
@凌驾
公共无效申报人(可丢弃的e){
Log.e(标记“onError:+e.getLocalizedMessage());
}
@凌驾
未完成的公共空间(){
Log.d(标签“onComplete:”);
}
});
addToDisposable(可处置观察员);
}
}
Repository.java
公共类存储库{
静态可观察列表可观察;
公共静态可观察getStringObservable(){
if(listObservable==null)
listObservable=observeable.fromCallable(()->{
列表字符串=新的ArrayList();
对于(int i=0;i<1000;i++){
字符串。添加(“字符串”+i);
}
Thread.sleep(5000);//模拟网络调用
返回字符串;
}).replay(1).自动连接();
可观察的回报率;
}
}
FragmentB代码为空,因此未过帐。从FragmentB按回时可以观察到问题
希望我的问题是清楚的。提前谢谢 这里的replay().autoConnect()
没有问题。您正在处理组合,这将阻止任何未来的观察者接收数据。使用clear()
代替。谢谢!!!它很好用。所以,dispose
会终止源可观察对象本身吗?如果不是,如果我真的想在以后的时间点终止热可观察对象呢。它处理试图使用自动连接的消费者。查找自动连接的重载以停止其源。
public class BaseFragment extends Fragment{
private CompositeDisposable mCompositeDisposable;
private ProgressDialog mProgressBar;
protected void addToDisposable(Disposable disposable) {
if (mCompositeDisposable == null) mCompositeDisposable = new CompositeDisposable();
mCompositeDisposable.add(disposable);
}
@Override
public void onDestroyView() {
super.onDestroyView();
if (mCompositeDisposable != null) {
mCompositeDisposable.dispose();
}
}
public void showProgress(String message) {
if (mProgressBar == null) {
mProgressBar = new ProgressDialog(getContext());
mProgressBar.setCancelable(false);
}
mProgressBar.setMessage(message);
mProgressBar.show();
}
public void dismissProgress() {
if (mProgressBar != null && mProgressBar.isShowing()) {
mProgressBar.dismiss();
}
}
}
public class MainActivity extends AppCompatActivity {
private static final String TAG = "MainActivity";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
replaceFragment(new FragmentA());
}
public void replaceFragment(Fragment fragment) {
FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction();
fragmentTransaction.replace(R.id.container, fragment);
fragmentTransaction.addToBackStack(fragment.getClass().getName());
fragmentTransaction.commit();
}
}
public class FragmentA extends BaseFragment {
private TextView textView;
private Button button;
private static final String TAG = "FragmentA";
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragmenta, container, false);
textView = (TextView) view.findViewById(R.id.txt);
button = view.findViewById(R.id.button);
button.setOnClickListener(v -> ((MainActivity) getActivity()).replaceFragment(new FragmentB()));
return view;
}
@Override
public void onActivityCreated(@Nullable Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
DisposableObserver<List<String>> disposableObserver = Repository.getStringObservable()
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.doOnNext(strings -> dismissProgress())
.doOnSubscribe(disposable -> showProgress("Please wait"))
.subscribeWith(new DisposableObserver<List<String>>() {
@Override
public void onNext(List<String> strings) {
StringBuilder stringBuilder = new StringBuilder();
for (String string : strings) {
stringBuilder.append(string).append("\n");
}
textView.setText(stringBuilder.toString());
}
@Override
public void onError(Throwable e) {
Log.e(TAG, "onError: " + e.getLocalizedMessage());
}
@Override
public void onComplete() {
Log.d(TAG, "onComplete: ");
}
});
addToDisposable(disposableObserver);
}
}
public class Repository {
static Observable<List<String>> listObservable;
public static Observable<List<String>> getStringObservable() {
if (listObservable == null)
listObservable = Observable.fromCallable(() -> {
List<String> strings = new ArrayList<>();
for (int i = 0; i < 1000; i++) {
strings.add("String " + i);
}
Thread.sleep(5000);// mocking network call
return strings;
}).replay(1).autoConnect();
return listObservable;
}
}