匿名类保存对封闭类的引用。
在下面的示例中,我创建了一个小型 Activity 。在 onCreate 方法中,我只是在另一个线程上添加一个计时器,添加一个 CompositeDisposable 并在 onDestroy 中清除它。
显然,如果没有CompositeDisposable,就会造成内存泄漏。使用 CompositeDisposable 它不会造成任何内存泄漏,但它是如何工作的呢?
RxJava 是否只是中断线程并在每个回调上放置 null ?你能提供一些在 RxJava 源代码中起作用的行吗?我想它就在 dispose 方法附近。
public class MainActivity extends AppCompatActivity {
private String TAG = "MainActivity";
private CompositeDisposable composite = new CompositeDisposable();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
composite.add(Flowable
.just(1)
.timer(90, TimeUnit.SECONDS)
.subscribeOn(Schedulers.io())
.subscribeWith(new DisposableSubscriber<Long>() {
@Override
public void onNext(Long aLong) { sayHello(); }
@Override
public void onError(Throwable t) { sayHello(); }
@Override
public void onComplete() { sayHello(); }
}));
}
@Override
protected void onDestroy() {
super.onDestroy();
composite.clear();
}
public void sayHello () { Log.w(TAG, "Hello everyone"); }
最佳答案
正是在 dispose
的来源中方法。您也可以在 IDE 中跳转到库中方法的源代码,在 IntelliJ 中,它是 Windows 上的 Ctrl+B 或 ⌘B在 Mac 上,在 Eclipse 中为 F3。
无论如何,这是 dispose
的来源方法(我的评论):
@Override
public void dispose() {
if (disposed) { // nothing to do
return;
}
OpenHashSet<Disposable> set; // this is the same type as our field that holds the Disposables
synchronized (this) {
if (disposed) {
return; // another thread did it while we got our lock, so nothing to do
}
disposed = true; // setting this flag is safe now, we're the only ones disposing
set = resources; // the references are now in this local variable
resources = null; // our field no longer has the references
}
dispose(set); // from here on out, only this method has the references to the Disposables
}
然后是dispose(OpenHashSet<Disposable>)
的完整代码我们在上面最后一行调用的方法(主要是错误处理,我认为这是不言自明的):
/**
* Dispose the contents of the OpenHashSet by suppressing non-fatal
* Throwables till the end.
* @param set the OpenHashSet to dispose elements of
*/
void dispose(OpenHashSet<Disposable> set) {
if (set == null) {
return;
}
List<Throwable> errors = null;
Object[] array = set.keys();
for (Object o : array) {
if (o instanceof Disposable) {
try {
((Disposable) o).dispose();
} catch (Throwable ex) {
Exceptions.throwIfFatal(ex);
if (errors == null) {
errors = new ArrayList<Throwable>();
}
errors.add(ex);
}
}
}
if (errors != null) {
if (errors.size() == 1) {
throw ExceptionHelper.wrapOrThrow(errors.get(0));
}
throw new CompositeException(errors);
}
}
如您所见,在该方法的末尾,set
现在可以进行垃圾收集,因为没有人持有对它的引用。
关于java - RxJava的clear(CompositeDisposable)方法内部是如何工作的?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42873048/