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;
 }
}