1.activity创建完毕后,ActivityThead调用performLaunchActiity,方法中为activity设置上下文变量Context,然后调用activity.attach(...)。在attach方法中,创建一个window对象,设置window的回调(比如,onAttachToWindow,onDetachFromWindow,onDispatchTouchEvent),将acitivity传入,window.setCallback(this)。
2.activity调用setContentView,源码中调用getWindow.setContentView,phoneWindow中的setContentView,首先判断decorView是否为null,为null,generateDecor创建一个空的decorView,然后调用generateLayout来加载具体的布局到decorView中,decorView.findViewById(android.r.id.content)拿到mContentParent。将我们的xml设置给mContentParent。方法为LayoutInflater.inflate(R.layout.xxx,mContentPartent)。最后回调activity的onContentChange。
这个时候decorview和window已经关联了。但是并没有被windowManager识别,WindowManager是管理window的唯一入口,他代理的是WindowManagerGlobal类。window是一个抽象的概念,是一个功能的集合。这个时候window还无法提供具体的功能,因为他无法接受外界的输入消息。
3.ActivityThread调用handleResumeActivity调用activity的onResume方法,然后调用activity的makeVisiable方法。在makeVisiable方法中,getWindowManager.addView(decorView,params),实际调用windowManagerGlobal的addView().windowManagerGlobal中维护着四个重要的集合.
private final ArrayList<View> mViews = new ArrayList<View>();
private final ArrayList<ViewRootImpl> mRoots = new ArrayList<ViewRootImpl>();
private final ArrayList<WindowManager.LayoutParams> mParams =
new ArrayList<WindowManager.LayoutParams>();
private final ArraySet<View> mDyingViews = new ArraySet<View>();
root = new ViewRootImpl(view.getContext(), display);
新建viewRootImpl(),存入mRoots中,viewrootimpl调用requestLayout,方法中调用schedualTraversals,里面通过一个代理类ManagerSession使用Binder机制,调用WindowManagerService中的addView,
viewroot是更新view和添加window的关键。
网友评论