View所持有的AttachInfo来自于根布局的ViewRootImpl。
同一个window下的view,持有的AttachInfo都是同一份。
1、View#AttachInfo:当view 被跟父window关联起来时,被设置给view的一系列信息。
A set of information given to a view when it is attached to its parent window.
@UnsupportedAppUsage
final IWindowSession mSession;
@UnsupportedAppUsage
final IWindow mWindow;
final IBinder mWindowToken;
Display mDisplay;
final Callbacks mRootCallbacks;
IWindowId mIWindowId;
WindowId mWindowId;
/**
* The top view of the hierarchy.
*/
View mRootView;
IBinder mPanelParentWindowToken;
boolean mHardwareAccelerated;
boolean mHardwareAccelerationRequested;
ThreadedRenderer mThreadedRenderer;
List<RenderNode> mPendingAnimatingRenderNodes;
...
2、何时、哪里生成的:ViewRootImpl
ViewRootImpl的构造函数中:
ViewRootImpl(Context context, Display display, IWindowSession session, boolean useSfChoreographer){
mAttachInfo = new View.AttachInfo(mWindowSession, mWindow, display, this, mHandler, this, context);
}
3、何时设置给View?
①activity启动时,渲染布局:
--> ViewRootImpl#doTraversal()
--> ViewRootImpl#performTraversals()
--> Decorview#dispatchAttachedToWindow(AttachInfo info, int visibility)
--> ViewGroup#dispatchAttachedToWindow(AttachInfo info, int visibility)
--> View#dispatchAttachedToWindow(AttachInfo info, int visibility): the android.view.View.AttachInfo to associated with this view
②动态添加View:比如点击button时,给root添加子View。
示例代码:
LinearLayout root = findViewById(R.id.root);
Button btn = findViewById(R.id.btn_add);
btn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
View view = new View(DispatchAttachInfoTestActivity.this);
view.setBackgroundColor(getResources().getColor(R.color.background_info));
LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(300, 300);
root.addView(view, lp);
}
});
调用栈:
--> View.OnClickListener#onClick(View v)
--> ViewGroup#addView(View child, LayoutParams params)
--> ViewGroup#addView(View child, int index, LayoutParams params)
--> ViewGroup#addViewInner(View child, int index, LayoutParams params, boolean preventRequestLayout)
--> View#dispatchAttachedToWindow(AttachInfo info, int visibility)
总结
①View#AttachInfo由ViewRootImpl生成,mAttachInfo实例维护在ViewRootImpl中。
②最先设置给根root。
③当view树中添加新的View时,会由parent将其mAttachInfo设置给child。
最终保证了整个View数中的View#AttachInfo是同一个对象。