You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 

3.3 KiB

Activity 的显示原理
  1. Activity 的显示原理(Window/DecorView/ViewRoot)
  2. Activity 的 UI 刷新机制(Vsync/Choreographer)
  3. UI 的绘制原理(Measure/Layout/Draw)
  4. Surface 原理(Surface/SurfaceFlinger)

显示原理

  1. setContentView 原理是什么?
  2. Activity 在 onResume 之后才会显示的原因是什么?
  3. ViewRoot 是干嘛的,是 View Tree 的 rootView 么?
public void setContentView(int layoutResID) {
	getWindow().setContentView(layoutResID);
	//...
}
final void attach(Context context, ){
	mWindow = new PhoneWindow(this);
}
// PhoneWindow#setContentView
public void setContentView(int layoutResID) {
    if(mContentParent == null) {
        installDecor();
    }
    mLayoutInflater.inflate(layoutResID, mContentParent);
}

private void installDecor() {
    // FrameLayout
    mDecor = new DecorView(getContext());
    // 根据 Window Feature 选择一个系统布局
    View in = mLayoutInflater.inflate(layoutResource, null);
    mDecor.addView(in, ...);
    mContentParent = findViewById(ID_ANDROID_CONTENT);
}
final void handleResumeActivity(IBinder token) {
	ActivityClientRecord r = performResumeActivity(token, );
    final Activity a = r.activity;
    
    if(r.window == null && !a.mFinished) {
        r.window = r.activity.getWindow();
        View decor = r.window.getDecorView();
        
        ViewManager wm = a.getWindowManager();
        a.mDecor = decor;
        wm.addview(decor, l);
    }
    r.activity.makeVisible();
}
// ViewManager#addView
void addView(View view, ViewGroup.LayoutParams params, ){
	ViewRootImpl root = new ViewRootImpl(view.getContext(), );
    root.setView(view, wparams, panelParentView);
}
// ViewRootImpl#setView
public void setView(View view, ) {
    if(mView == null) {
        mView = view;
        requestLayout();
        //...
        mWindowSession.addToDisplay(mWindow, ...);
    }
}
public void requestLayout() {
	scheduleTraversals();
}
void scheduleTraversals() {
    mChoreographer.postCallback(..., mTraversalRunnable, null);
}
class TraversalRunnable implements Runnable {
    public void run() {
        doTraversal();
    }
}
void doTraversal() {
    performTraversals();
}
private void performTraversals() {
    //...
    relayoutWindow(params, ...);
    performMeasure(childWidthMeasureSpec, ...);
    performLayout(lp, desiredWindowWidth, ...);
    performDraw();
}
// 向 WMS 申请 Surface
int relayoutWindow(WindowManager.LayoutParams params, ...) {
    mWindowSession.relayout(..., mSurface);
}
// static class W extends IWindow.Stub {...}
mWindowSession.addToDisplay(mWindow, ...);
public int addToDisplay(IWindow window, int seq, ...) {
    // WMS 统一管理 Window,分配 Surface
    return mService.addWindow(this, window, seq, attrs, ...);
}

IWindowManager windowManager = getWindowManagerService();
sWindowSession = windowManager.openSession(...);

IWindowSession openSession(IWindowSessionCallback callback, ...) {
    Session session = new Session(this, callback, client, inputContext);
    return session;
}

WMS 的主要作用:

  1. 分配 Surface
  2. 掌管 Surface 显示顺序以及位置尺寸等
  3. 控制窗口动画
  4. 输入事件分发

总结