Android 探究View onAttachedToWindow 触发时机
我们先从的说起。会调用当前的通过递归调用,会逐级调用 parent 的,最终会走到的 因为的 parent 是,所以最终会走调用后续会执行精简代码如下:调用方法,从逻辑中我们发现 host 其实就是。所以就相当于 因为也是一个 ViewGroup ,并且没有覆写方法。所以我们直接看的方法 的方法 ,遍历 子view , 然后调用。发现 的会调用 。到此 , 已经分析完。..............
转载请标明出处:http://blog.csdn.net/zhaoyanjun6/article/details/125607542
本文出自【赵彦军的博客】
文章目录
生命周期观察
Activity
class MainActivity : AppCompatActivity() {
private lateinit var binding: ActivityMainBinding
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityMainBinding.inflate(layoutInflater)
setContentView(binding.root)
Log.d("yu--", "Activity onCreate")
}
override fun onResume() {
super.onResume()
Log.d("yu--", "Activity onResume")
}
override fun onAttachedToWindow() {
super.onAttachedToWindow()
Log.d("yu--", "Activity onAttachedToWindow")
}
override fun onPause() {
super.onPause()
Log.d("yu--", "Activity onPause")
}
override fun onStop() {
super.onStop()
Log.d("yu--", "Activity onStop")
}
override fun onDestroy() {
super.onDestroy()
Log.d("yu--", "Activity onDestroy")
}
override fun onDetachedFromWindow() {
super.onDetachedFromWindow()
Log.d("yu--", "Activity onDetachedFromWindow")
}
}
MyView
public class MyView extends View {
public MyView(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
}
@Override
protected void onAttachedToWindow() {
super.onAttachedToWindow();
}
@Override
protected void onDetachedFromWindow() {
super.onDetachedFromWindow();
}
}
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<com.example.myapplication.MyView
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</FrameLayout>
生命周期回调:
D/yu--: Activity onCreate
D/yu--: Activity onResume
D/yu--: Activity onAttachedToWindow
D/yu--: View onAttachedToWindow
D/yu--: Activity onPause
D/yu--: Activity onStop
D/yu--: Activity onDestroy
D/yu--: View onDetachedFromWindow
D/yu--: Activity onDetachedFromWindow

从回调的结果来看:
- 1、Activity onResume 之后回调 onAttachedToWindow
- 2、Activity onDestroy 之后回调 onDetachedFromWindow
- 3、Activity 的 onAttachedToWindow 回调之后,才会回调 view 的 onAttachedToWindow
- 4、View onDetachedFromWindow 回调之后,才会回调 Activity onDetachedFromWindow
源码探究
当 Activity 发生 resume 的时候,实际上是 ActivityThread 的 handleResumeActivity() 被调用。
performResumeActivity方法,会执行 activity 的 onResume 方法。

WindowManagerImpl.java
这里的 mGlobal 就是 WindowManagerGlobal 类
我们看 WindowManagerGlobal 的 addView 方法

也就是说 , WindowManagerGlobal 的 addView 方法 ,创建了 ViewRootImpl , 然后建立 DecorView 和 ViewRootImpl 绑定关系。
回到正题,继续看 ViewRootImpl 的 requestLayout()

scheduleTraversals() 后续会执行 doTraversal();

精简代码如下:

调用 host.dispatchAttachedToWindow 方法,从逻辑中我们发现 host 其实就是 DecorView 。
所以就相当于 DecorView.dispatchAttachedToWindow
因为 DecorView 也是一个 ViewGroup ,并且没有覆写 dispatchAttachedToWindow 方法。
所以我们直接看 ViewGroup 的 dispatchAttachedToWindow 方法。

ViewGroup 的 dispatchAttachedToWindow 方法 ,首先会调用 super.dispatchAttachedToWindow,实际上是回调当前 ViewGroup 的 onAttachedToWindow 。
然后遍历 子view , 然后调用 child.dispatchAttachedToWindow 。

发现 View 的 dispatchAttachedToWindow 会调用 onAttachedToWindow 。
到此 ,onAttachedToWindow 已经分析完。
当一个view 被 add 的时候
我们先从 ViewGroup 的 addView 说起。
会调用当前 ViewGroup 的 requestLayout()

通过递归调用,会逐级调用 parent 的 requestLayout() ,最终会走到 DecorView 的 requestLayout()
因为 DecorView 的 parent 是 ViewRootImpl ,所以最终会走ViewRootImpl 调用 requestLayout()
下面的逻辑,我们就不分析了,和上面分析的一致。
Activity onAttachedToWindow 是怎么触发的?
首先,我们来看看 Activity 的 onAttachedToWindow 长什么样子的?
Activity 实现了 Window.Callback , 并且实现了 onAttachedToWindow 、 onDetachedFromWindow
代码如下:


看 Activity 的 attach 方法,调用了 mWindow.setCallback(this)

mWindow 是 PhoneWindow , 看看 PhoneWindow 的 setCallback

到这里我们基本明白了,Activity 的 onAttachedToWindow 是什么。
剩下的,我们只要知道 window.mcallback 接口实例,在什么情况下会被调用,就能知道触发时机了。
看看 DecorView 的 onAttachedToWindow 的方法。
- 首先
DecorView的onAttachedToWindow会调用 - 然后
callback的onAttachedToWindow会被调用
这个 callback 是 在 Activity 中实现的的接口 , 所以 Activity 的 onAttachedToWindow 就会被调用
结论:
Activity的onAttachedToWindow在DecorView的onAttachedToWindow被调用时触发
OnAttachStateChangeListener
在 dispatchAttachedToWindow 的代码中,我们发现 除了 onAttachedToWindow 方法会执行外,OnAttachStateChangeListener 也会回调,mOnAttachStateChangeListeners 是一个集合,可以有多个 Listener

使用如下:
public class MyView extends View {
public MyView(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
addOnAttachStateChangeListener(new OnAttachStateChangeListener() {
@Override
public void onViewAttachedToWindow(View v) {
}
@Override
public void onViewDetachedFromWindow(View v) {
}
});
}
}
在 onAttachedToWindow 能获取到 View 的宽高吗?
答案:不能,因为 onAttachedToWindow 在回调时,还没有 measure , layout

当子view 被 add 的时候,会触发View树上其他View回调 onAttachedToWindow 吗?
答案:不会,只会触发当前子view 的 onAttachedToWindow 被回调,其他View 不会触发。

更多推荐



所有评论(0)