Android中Window添加View的底层原理

2019-12-10 18:54:25刘景俊

3).通过ViewRootImpl来更新界面并完成window的添加过程 。
root.setView(view, wparams, panelParentView);  
上面的root就是ViewRootImpl,setView中通过requestLayout()来完成异步刷新,看下requestLayout:

public void requestLayout() { 
    if (!mHandlingLayoutInLayoutRequest) { 
      checkThread(); 
      mLayoutRequested = true; 
      scheduleTraversals(); 
    } 
  } 

接下来通过WindowSession来完成window添加过程,WindowSession是一个Binder对象,真正的实现类是 Session,window的添加是一次IPC调用。

 try { 
          mOrigWindowType = mWindowAttributes.type; 
          mAttachInfo.mRecomputeGlobalAttributes = true; 
          collectViewAttributes(); 
          res = mWindowSession.addToDisplay(mWindow, mSeq, mWindowAttributes, 
              getHostVisibility(), mDisplay.getDisplayId(), 
              mAttachInfo.mContentInsets, mAttachInfo.mStableInsets, mInputChannel); 
        } catch (RemoteException e) { 
          mAdded = false; 
          mView = null; 
          mAttachInfo.mRootView = null; 
          mInputChannel = null; 
          mFallbackEventHandler.setView(null); 
          unscheduleTraversals(); 
          setAccessibilityFocus(null, null); 
          throw new RuntimeException("Adding window failed", e); 
} 

 在Session内部会通过WindowManagerService来实现Window的添加。

public int addToDisplay(IWindow window, int seq, WindowManager.LayoutParams attrs, 
     int viewVisibility, int displayId, Rect outContentInsets, Rect outStableInsets, 
     InputChannel outInputChannel) { 
   return mService.addWindow(this, window, seq, attrs, viewVisibility, displayId, 
       outContentInsets, outStableInsets, outInputChannel); 
 }