【发布时间】:2021-05-01 18:24:05
【问题描述】:
我需要在适配器解析其视图后几毫秒开始观察,以便它们正确接收信号。
此方法在 onViewCreated() 之后执行;
pageControllerAdapter.submitList(stringVisitors, () -> {
if (!currentPage.hasActiveObservers()) {
Post.delayed(
() -> {
Post.onMain(
() -> {
currentPage.observe(getViewLifecycleOwner(),
page -> {
selector.setSelected(page);
binding.searchPages.setCurrentItem(page, true);
}
);
}
);
},
150L,
TimeUnit.MILLISECONDS
);
}
});
Post.delayed() 是 Executors.newSingleThreadScheduledExecutor().schedule() 方法,Post.onMain() 是 new Handler(Looper.getMainLooper()); 用于 Runnable 发布
有些奇怪的事情正在发生……:
第一次执行代码时一切正常,但在配置更改后出现IllegalStateException:
@MainThread
@NonNull
public LifecycleOwner getViewLifecycleOwner() {
if (mViewLifecycleOwner == null) {
throw new IllegalStateException("Can't access the Fragment View's LifecycleOwner when "
+ "getView() is null i.e., before onCreateView() or after onDestroyView()");
}
return mViewLifecycleOwner;
}
但是...如果我打电话给getViewLifeCycleOwner();在进入.getMainLooper() 线程之前,在Post.delayed() 和Post.onMain() 之间像这样:
Post.delayed(
() -> {
getViewLifecycleOwner();
Post.onMain(
() -> {
currentPage.observe(getViewLifecycleOwner(),
page -> {
selector.setSelected(page);
binding.searchPages.setCurrentItem(page, true);
}
);
}
);
},
150L,
TimeUnit.MILLISECONDS
);
代码有效....
我怀疑发生了什么,这是……:
/**
* The provider that owns this Lifecycle.
* Only WeakReference on LifecycleOwner is kept, so if somebody leaks Lifecycle, they won't leak
* the whole Fragment / Activity. However, to leak Lifecycle object isn't great idea neither,
* because it keeps strong references on all other listeners, so you'll leak all of them as
* well.
*/
private final WeakReference<LifecycleOwner> mLifecycleOwner;
WeakReference 正在 Post.delayed()(预定的执行程序)内进行 GC,因此当需要再次在 mainThread 中执行该方法时,该引用已被收集,但是当第二次执行方法在后台调度执行器中执行,即使引用根本没有被使用,方法getViewLifeCycleOwner()所涉及的所有引用的副本都被线程保留并在返回mainThread时逃脱垃圾回收。
我的预感正确吗?
【问题讨论】:
标签: java android multithreading android-lifecycle weak-references