我遇到了replay().autoconnect()
运算符组合的一些问题。
在我提出问题之前,让我分享一下我对这些操作员的一些了解。我一直关注这个tutorial on multicasting
我理解的是
replay()
运算符可以在新订阅者进入时重新发出observable的结果,而无需重新执行源observable(在网络调用期间帮助)autoconnect()
可以将observable转换为热的observable,这样即使所有订阅者都离开并且稍后新的订阅者进入,observable仍然会处于活动状态并通过{{1}重新发出结果} 所以,我发现replay()
组合适合我的网络电话。
在我的应用程序中,我使用了所有碎片,并在replay().autoConnect()
我保留BaseFragment
一次性使用。片段生命周期中我所有的一次性用品我继续在Composite
和CompositeDisposable
事件中添加,我处理一次性用品,因为我不想听取可观察的排放量片段不可见时。
我有一个用例,我在一个片段中进行网络调用,比如说onDestroyView
,然后转到FragmentA
而不会杀死FragmentB
(我正在进行片段替换)。后来我可以从后台回到FragmentA
。
当我从FragmentA
移动到FragmentA
时,显然我的观察者会被处理掉,但我期望的是,当我稍后回到FragmentB
时,我应该立即获得旧的网络通话结果我在observable上使用FragmentA
。
但是在这里发生了一些奇怪的事情,我可以看到旧的observable仍然存在,但它没有发出任何值。
如果我将replay().autoConnect()
更改为mCompositeDisposable.dispose();
而不是onDestroy()
,则按预期方式工作
根据教程, autoconnect()即使所有观察者都离开也不会终止观察
但在我的情况下,当所有观察者离开并且后来新观察者进来时,它不会仅发射,并且因为它触发了onDestroyView()
所有我能看到的是一个无限加载对话框UI(因为我在doOnsubscribe()
上显示加载器)。我发布了一个完全复制我的问题的示例代码。
BaseFragment.java
doOnsubscribe
MainActivity.java
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();
}
}
}
FragmentA.java
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();
}
}
Repository.java
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);
}
}
FragmentB代码因为空而没有发布。从FragmentB按回来时可以发现问题。
希望我的问题很明确。提前致谢!!