这个是本人总结的,mkw的framework面试的资料,需要具体的视频和其他的资料,TB店铺 纳新工作室 中找framework 资料就好哈。
1.Activity的显示原理
(Window/DecorView/ViewRoot)
1.1 setContentView 的原理是什么
public boid setContentView(int layoutResiId){
getWindow().setContentView(layoutResID);
...
}
public Window getWindow(){
return mWindow;
}
private Window mWindow;
window是在activity的attach函数里面初始化的
final void attach(Context context,...){
...
mWindow = new PhoneWindow(this);
...
}
对于activity的创建:performLaunchActivity 中
1.创建Activity对象 2.创建Context对象 3.准备Application 对象
4.attach 上下文 5.Activity onCreate
PhoneWindow.java 的setContentView
public void setContentView(int layoutResID){
if(mContentParent == null){//view container 用来装contentView
installDecor();
}//resID 生成VireTree
mLayoutInflater.inflate(layoutResID,mContentParent);
//contentParent 是ViewTree的parent,把生成的view加入到parent里面。
}
private void installDecor(){
//DecorView 是一个framelayout,是rootview
mDecor = new DecorView(getContext());
View in = mLayoutInflater.inflate(layoutResourece,null);//系统布局
mDecor.addView(in,...);
//找到contentParent
mContentParent = findViewById(ID_ANDROID_CONTENT);
}
创建DecorView 然后加载系统布局,找到ContentView,将我们的layout加载进布局里面。
创建了一套view tree的数据结构
页面显示在onResume 之后
final void handleResumeActivity(IBider token,...){
ActivityClientRecord r = performResumeActivity(token);//onResume
final Activity a = r.activity;
if(r.window == null && !a.mFinished){//UI 显示问题
r.window = r.activity.getWindow();
View decor = r.window.getDecorView();
WiewManager wm = a.getWindowManage();
a.mDecor = decor;
wm.addView(decor,I);
}
r.activity.makeVisible();
//mDecor.setVisibility(View.VISIABLE);
}
void addView(View view,ViewGroup.LayoutParams params,...){
ViewRootImpl root = new ViewRootImpl(view.getContext());
root.setView(view,wparams,panelParentView);
}
public void setView(View view,...){
if(mView ==null){
mView = view;
requestLayout();//触发第一次绘制
...
mWindowSession.addToDisplay(mWindow,...);//binder调用
}
}
public void requestLayout(){
...
schedultTraversal();
}
void scheduleTraversals(){
...
mChoreographer.postCallback(...,mTraversalRunnable,null);
}
class TraversalRunnable implements Runnable{
public void run(){
doTraversal();
}
}
void doTraversal(){
performTraversals();//执行绘制的
}
private void performTraversals(){
...
relayoutWindow(params,...);//向ws 申请surface
//mWindowSession.relayout(...,mSurface);
...
performMeasure(childWidthMeasureSpec);
...
performLayout(lp,desiredWindowWidth,...);
...
performDraw();
}
windowSession 的作用:
IWindowManager windowManager = getWindowManagerService();
sWindowSession = windowManager.openSession(...);}
openSession:
WindowSession 就是给应用和ws通信的。可以通过这个向wms发起binder调用
IWindowSession openSession(IWindowSessionCallback callback,...){
Session session = new Session(this,callback,client,inputContext);
return session;
}
addToDisplay(mWindow){//mWindow extend IWindow
return mService.addWindow(this,window,seq,attrs,...);
//会在WM中创建一个Window相关的对象,Ws来管理window相关的层级,位置,大小
//WMs的重要作用就是给应用端的window分配surface,并且管理surface的显示顺序,
//位置 尺寸
//当应用端在surface上绘制完成开始显示之后,surfaceFlinger就开始按照WMS的surface的层级,大小
//来进行合成,最后写道屏幕的缓冲区。
WMS主要作用:1.分配surface 2.掌管surface显示顺序以及位置尺寸等
3.控制窗口动画 4.输入事件分发
}
Activity启动会创建phoneWindow对象,PhoneWindow会创建DecorView对象。
DecorVIew里面有个对象viewRootImpl,里面包含了ContentView,ContentView会resLayout 的parent
DecorView中的ViewRootImpl可以和WMS进行双向通信,ViewRootImpl持有WMS的binder,IWindowSession
WMS持有ViewRootImpl 的binder对象IWIndow。然后他们就可以双向通信了。
主要的流程是:WMS给应用端的window创建surface,管理surface的显示顺序,位置,大小。当应用在surface。
上绘制完成之后开始显示的时候,surfceFlinger 开始根据WMS 的对于surface的显示顺序和位置,大小,开始去。显示surface。
经常会问到的问题:
1.2 Activity在OnResume才能显示的原理
1.3 ViewRoot是干嘛的,是不是virew Tree的rootView?
2.Activity 的UI刷新机制(Vsync/Choreographer)
3.UI的绘制原理(Measure/layout/draw)
4.Surface 原理(Surface/SurfaceFlinger)
Activity的显示原理:
PhoneWindow是什么,怎么创建的 在attach 的时候创建PhoneWindow
setContentView原理,DecorView是什么?
ViewRoot是什么?有什么作用?
ViewRoot对应于ViewRootImpl类,它是链接WindowManager和DecorView的纽带,View的三大流程均是通过ViewRoot来完成的
VIew显示原理,WMS发挥什么作用。