ViewTreeLifecycleOwner是什么?
ViewTreeLifecycleOwner是Lifecycle KTX中提供的View的一个扩展方法,可以快速地获取一个最近的Fragment或者Activity的LifecycleOwner。
view.findViewTreeLifecycleOwner()
实现原理?
ComponentActivity
通过ViewTreeLifecycleOwner.set
将当前lifecycle设置到decorView
@Override
public void setContentView(@LayoutRes int layoutResID) {
// Set the VTLO before setting the content view so that the inflation process
// and attach listeners will see it already present
ViewTreeLifecycleOwner.set(getWindow().getDecorView(), this);
super.setContentView(layoutResID);
}
Fragment
通过ViewTreeLifecycleOwner.set
将mViewLifecycleOwner设置到mView
void performCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container,
@Nullable Bundle savedInstanceState) {
...
ViewTreeLifecycleOwner.set(mView, mViewLifecycleOwner);
ViewTreeLifecycleOwner
ViewTreeLifecycleOwner.set
的实现很简单,仅仅是使用setTag
进行设置
public static void set(@NonNull View view, @Nullable LifecycleOwner lifecycleOwner) {
view.setTag(R.id.view_tree_lifecycle_owner, lifecycleOwner);
}
然后通过不断循环遍历parent获取最近的lifecycleOwner:
public static LifecycleOwner get(@NonNull View view) {
LifecycleOwner found = (LifecycleOwner) view.getTag(R.id.view_tree_lifecycle_owner);
if (found != null) return found;
ViewParent parent = view.getParent();
while (found == null && parent instanceof View) {
final View parentView = (View) parent;
found = (LifecycleOwner) parentView.getTag(R.id.view_tree_lifecycle_owner);
parent = parentView.getParent();
}
return found;
}
}
总结
随着MVVM的普及,我们可能需要在View内部基于lifecycle进行livedata订阅等工作,当View嵌套比较深时,使用ViewTreeLifecycleOwner扩展方法可以避免lifecycle的层层传递,简化代码