假设我有这样一个片段。
class MyFragment : Fragment() {
// Suppose there is a binding, which contains a recyclerView
private var _binding: FragmentAbinding? = null
val binding get() = _binding!!
// Suppose there is a recyclerView adapter
val adapter by lazy { MyAdapter() }
// use navigation as router
private val navController: NavController by lazy { findNavController() }
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View {
_binding = FragmentAbinding.inflate(
inflater,
container,
false
)
return binding.root
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
// ...
binding.recyclerView.adapter = adapter
// ...
}
override fun onDestroyView() {
_binding = null
}
}
当使用navController.anavigation(…(时,MyFragment将被替换,绑定为空。但是,由于recyclerView使用观察者模式来观察适配器中的数据集,因此适配器将持有recyclerView作为其观察者。在导航到另一个片段(即onDestroyView((之后(后,recyclerView是否会主动取消对适配器数据集的观察,这意味着适配器不会持有recyclerView的实例?
我使用以下方法删除适配器数据集观察器
fun RecyclerView.Adapter<*>.removeObservers() {
var clazz: Class<*> = javaClass
val simpleName = RecyclerView.Adapter::class.simpleName
while (clazz.simpleName != simpleName) {
clazz = clazz.superclass
}
val field = clazz.getDeclaredField("mObservable")
field.isAccessible = true
val observable = field[this] as Observable<*>
observable.unregisterAll()
}
// in fragment
class MyFragment : Fragment() {
override fun onDestroyView() {
adapter.removeObservers()
}
}
调用时的适配器"onCreateViewHolder";使用recyclerView作为视图组。当您使用导航进行导航时,您的片段只查看了已销毁的片段,但其实例在后台仍处于活动状态,而您的适配器也处于活动状态。因为这是解决此问题的类级变量,您应该在视图生命周期事件中创建适配器(onViewCreated.onDestroyView(。