问题
在引入Rxjava的时候,要对Rxjava进行统一管理,便引进了CompositeSubscription类来统一管理。
绑定:
mCompositeSubscription.add(o.subscribeOn(Schedulers.io())
.unsubscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(s));
解绑:
if (mCompositeSubscription != null && mCompositeSubscription.hasSubscriptions()) {
mCompositeSubscription.unsubscribe();
}
后来在使用过程中发现一个问题,在调用解绑之后,重新绑定Rxjava会无效。 遂查资料。
A warning! Once you call CompositeSubscription.unsubscribe() the object is unusable, as it will automatically unsubscribe anything you add to it afterwards! You must create a new CompositeSubscription as a replacement if you plan on re-using this pattern later.
即在调用CompositeSubscription.unsubscribe() 之后这个CompositeSubscription对象就将不能再使用了,后续所有新添加进来的会马上进行解绑。如果想继续使用就只能重新创建对象。
所以解决方案:
protected <T> void toSubscribe(Observable<T> o, Subscriber<T> s) {
if (mCompositeSubscription == null) {
mCompositeSubscription = new CompositeSubscription();
}
mCompositeSubscription.add(o.subscribeOn(Schedulers.io())
.unsubscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(s));
}
protected void onUnsubscribe() {
//CompositeSubscription 一旦解绑之后该CompositeSubscription就不能继续使用了。
if (mCompositeSubscription != null && mCompositeSubscription.hasSubscriptions()) {
mCompositeSubscription.unsubscribe();
//解绑完不置null第二次绑定会有问题。
mCompositeSubscription = null;
}
}
回过头来CompositeSubscription 源码发现里面有两个相近的方法;clear()和unsubscribe()。
public void clear() {
if (!unsubscribed) {
Collection<Subscription> unsubscribe;
synchronized (this) {
if (unsubscribed || subscriptions == null) {
return;
} else {
unsubscribe = subscriptions;
subscriptions = null;
}
}
unsubscribeFromAll(unsubscribe);
}
}
@Override
public void unsubscribe() {
if (!unsubscribed) {
Collection<Subscription> unsubscribe;
synchronized (this) {
if (unsubscribed) {
return;
}
unsubscribed = true;
unsubscribe = subscriptions;
subscriptions = null;
}
// we will only get here once
unsubscribeFromAll(unsubscribe);
}
}
发现这两个方法其实就一个地方的差别,就是在unsubscribe()中将unsubscribed = true; 那这个有什么作用?
在看看CompositeSubscription的add()方法
public void add(final Subscription s) {
if (s.isUnsubscribed()) {
return;
}
if (!unsubscribed) {
synchronized (this) {
if (!unsubscribed) {
if (subscriptions == null) {
subscriptions = new HashSet<Subscription>(4);
}
subscriptions.add(s);
return;
}
}
}
// call after leaving the synchronized block so we're not holding a lock while executing this
s.unsubscribe();
}
当unsubscribed为true的时候直接解绑了。
按照源码来看的话,出现解绑后还想继续用的话还有另一种方案,就是不调用unsubscribe(),直接调用clear()方法然后继续绑定新的继续使用,带完全确定没用之后再调用unsubscribe()。