ViewRootImpl入門
4579 ワード
きそ
それ自体はごく普通のクラスです(初期のViewRootImplはHandlerだったそうですがapi 23ではそうではありません).
Activity#handleResumeActivity()では、Activityに関連付けられたPhoneWindowオブジェクトのDecorViewがViewRootImpl#setView()に渡されます.一方、ViewRootImplによって測定、レイアウト、描画が行われるとともに、ViewRootImplはWMSと複雑に対話し、ActivityのUIを示す.まとめると、その役割は次のとおりです.
1は、Activity#setContentView()で生成されたぺこぺこしたViewツリーを、Viewに塗りつぶします.
2,WMSとコミュニケーションをとり,表示するインタフェースを管理する.
コンストラクタ
ActivityThread#handleResumeActivity()->WindowManagerImpl#addView()->WindowManagerGlobal#addView()->ViewRootImpl(view.getContext(),Display).
コンストラクション関数では、ViewRootImplのグローバル変数mContextに最初のパラメータが割り当てられます.handleResumeActivityによって伝達するViewオブジェクトはWindow#mDecorであるのでview.getContext()は、DecorViewが指すActivityインスタンスを返します.
一部のコンストラクション関数のコードは次のとおりです. mWindowSession = WindowManagerGlobal.getWindowSession();
mWindow = new W(this);
mAttachInfo = new View.AttachInfo(mWindowSession, mWindow, display, this, mHandler, this);
最初の文mWindowSessionはWindowManagerGlobalに割り当てられています.getWindowSession()は、値が1つのSessionオブジェクトであることを返し、Sessionのインスタンス化はWMSプロセスで行われ、本来は1つのSessionのエージェントオブジェクトがあるはずなので、Sessionによって主にWMSのいくつかのメソッドを呼び出すことができます.
第二、三句中のWはIWindowに継承する.Stubは,後者がBinderに継承され,IWindowインタフェースが実現されるため,このWはIPC可能である.3番目の文ではmWindowをViewに割り当てた.AttachInfoのmWindowオブジェクトは、mWindowSession変数にmWindowSessionを割り当てます.
setView
コンストラクション関数呼び出しタイミングと同じであり、Viewパラメータも同じである.したがって、ViewRootImplのmViewとは、このViewRootImplが依存するActivityのDecorViewを指す.したがって、mViewを呼び出すことで、ActivityコンポーネントのUIを描画することができます. public void setView(View view, WindowManager.LayoutParams attrs, View panelParentView) {
synchronized (this) {
if (mView == null) {
mView = view;
//
requestLayout();
//
try {
mOrigWindowType = mWindowAttributes.type;
mAttachInfo.mRecomputeGlobalAttributes = true;
collectViewAttributes();
res = mWindowSession.addToDisplay(mWindow, mSeq, mWindowAttributes,
getHostVisibility(), mDisplay.getDisplayId(),
mAttachInfo.mContentInsets, mAttachInfo.mStableInsets,
mAttachInfo.mOutsets, mInputChannel);
}
//
}
}
}
一方、requestLayout->scheduleTraversals()->Choreographer#postCallback()->postCallbackDelayedInternal()->scheduleFrameLocked()->scheduleFrameLocked()->scheduleFrameLocked()は、MSG_DO_FRAMEのmsg->doFrame()です.この過程でscheduleTransversals()のパラメータを追跡する必要があり,postCallbackDelayedInternal()までは正常に伝達されていた.postCallbackDelayedInternal()は次のとおりです. private void postCallbackDelayedInternal(int callbackType,
Object action, Object token, long delayMillis) {// scheduleTraversals() ,token Null,delayMills 0
synchronized (mLock) {
final long now = SystemClock.uptimeMillis();
final long dueTime = now + delayMillis;
mCallbackQueues[callbackType].addCallbackLocked(dueTime, action, token);
// CallbackRecord ,
if (dueTime <= now) {// delayMills 0,
scheduleFrameLocked(now);
} else {
Message msg = mHandler.obtainMessage(MSG_DO_SCHEDULE_CALLBACK, action);
msg.arg1 = callbackType;
msg.setAsynchronous(true);
mHandler.sendMessageAtTime(msg, dueTime);
}
}
}
doFrame()に着いたとき、こんな言葉がありました. doCallbacks(Choreographer.CALLBACK_TRAVERSAL, frameTimeNanos);
最初のパラメータはscheduleTransversals()の最初のパラメータであり、doCallBacks()ではCallbackRecord#run()が呼び出されます. public void run(long frameTimeNanos) {
if (token == FRAME_CALLBACK_TOKEN) {
((FrameCallback)action).doFrame(frameTimeNanos);
} else {
((Runnable)action).run();
}
}
したがって、ここではscheduleTransversals()の2番目のパラメータが実行されます.2番目のパラメータ->doTraversal()->performTraversals()は、このメソッドではViewのmeasure、layout、drawが実行されます.
ここでrequestLayout()メソッドは実行され、その役割はViewツリーを測定し、レイアウトし、描画することです.setView()では、mWindowSession#addToDisplay()も呼び出されます.mWindowSessionは、WMSによって作成されたSessionオブジェクトが本アプリケーションのエージェントであるため、mWindowSession#addToDisplay()は、WMSが存在するプロセスに実行されます.Sessionではこの方法は簡単で、パラメータ(thisはSessionオブジェクト自体を指す)を追加してWMS#addWindow()に渡すだけです.
ActivityThread#handleResumeActivity()->WindowManagerImpl#addView()->WindowManagerGlobal#addView()->ViewRootImpl(view.getContext(),Display).
コンストラクション関数では、ViewRootImplのグローバル変数mContextに最初のパラメータが割り当てられます.handleResumeActivityによって伝達するViewオブジェクトはWindow#mDecorであるのでview.getContext()は、DecorViewが指すActivityインスタンスを返します.
一部のコンストラクション関数のコードは次のとおりです.
mWindowSession = WindowManagerGlobal.getWindowSession();
mWindow = new W(this);
mAttachInfo = new View.AttachInfo(mWindowSession, mWindow, display, this, mHandler, this);
最初の文mWindowSessionはWindowManagerGlobalに割り当てられています.getWindowSession()は、値が1つのSessionオブジェクトであることを返し、Sessionのインスタンス化はWMSプロセスで行われ、本来は1つのSessionのエージェントオブジェクトがあるはずなので、Sessionによって主にWMSのいくつかのメソッドを呼び出すことができます.
第二、三句中のWはIWindowに継承する.Stubは,後者がBinderに継承され,IWindowインタフェースが実現されるため,このWはIPC可能である.3番目の文ではmWindowをViewに割り当てた.AttachInfoのmWindowオブジェクトは、mWindowSession変数にmWindowSessionを割り当てます.
setView
コンストラクション関数呼び出しタイミングと同じであり、Viewパラメータも同じである.したがって、ViewRootImplのmViewとは、このViewRootImplが依存するActivityのDecorViewを指す.したがって、mViewを呼び出すことで、ActivityコンポーネントのUIを描画することができます. public void setView(View view, WindowManager.LayoutParams attrs, View panelParentView) {
synchronized (this) {
if (mView == null) {
mView = view;
//
requestLayout();
//
try {
mOrigWindowType = mWindowAttributes.type;
mAttachInfo.mRecomputeGlobalAttributes = true;
collectViewAttributes();
res = mWindowSession.addToDisplay(mWindow, mSeq, mWindowAttributes,
getHostVisibility(), mDisplay.getDisplayId(),
mAttachInfo.mContentInsets, mAttachInfo.mStableInsets,
mAttachInfo.mOutsets, mInputChannel);
}
//
}
}
}
一方、requestLayout->scheduleTraversals()->Choreographer#postCallback()->postCallbackDelayedInternal()->scheduleFrameLocked()->scheduleFrameLocked()->scheduleFrameLocked()は、MSG_DO_FRAMEのmsg->doFrame()です.この過程でscheduleTransversals()のパラメータを追跡する必要があり,postCallbackDelayedInternal()までは正常に伝達されていた.postCallbackDelayedInternal()は次のとおりです. private void postCallbackDelayedInternal(int callbackType,
Object action, Object token, long delayMillis) {// scheduleTraversals() ,token Null,delayMills 0
synchronized (mLock) {
final long now = SystemClock.uptimeMillis();
final long dueTime = now + delayMillis;
mCallbackQueues[callbackType].addCallbackLocked(dueTime, action, token);
// CallbackRecord ,
if (dueTime <= now) {// delayMills 0,
scheduleFrameLocked(now);
} else {
Message msg = mHandler.obtainMessage(MSG_DO_SCHEDULE_CALLBACK, action);
msg.arg1 = callbackType;
msg.setAsynchronous(true);
mHandler.sendMessageAtTime(msg, dueTime);
}
}
}
doFrame()に着いたとき、こんな言葉がありました. doCallbacks(Choreographer.CALLBACK_TRAVERSAL, frameTimeNanos);
最初のパラメータはscheduleTransversals()の最初のパラメータであり、doCallBacks()ではCallbackRecord#run()が呼び出されます. public void run(long frameTimeNanos) {
if (token == FRAME_CALLBACK_TOKEN) {
((FrameCallback)action).doFrame(frameTimeNanos);
} else {
((Runnable)action).run();
}
}
したがって、ここではscheduleTransversals()の2番目のパラメータが実行されます.2番目のパラメータ->doTraversal()->performTraversals()は、このメソッドではViewのmeasure、layout、drawが実行されます.
ここでrequestLayout()メソッドは実行され、その役割はViewツリーを測定し、レイアウトし、描画することです.setView()では、mWindowSession#addToDisplay()も呼び出されます.mWindowSessionは、WMSによって作成されたSessionオブジェクトが本アプリケーションのエージェントであるため、mWindowSession#addToDisplay()は、WMSが存在するプロセスに実行されます.Sessionではこの方法は簡単で、パラメータ(thisはSessionオブジェクト自体を指す)を追加してWMS#addWindow()に渡すだけです.
public void setView(View view, WindowManager.LayoutParams attrs, View panelParentView) {
synchronized (this) {
if (mView == null) {
mView = view;
//
requestLayout();
//
try {
mOrigWindowType = mWindowAttributes.type;
mAttachInfo.mRecomputeGlobalAttributes = true;
collectViewAttributes();
res = mWindowSession.addToDisplay(mWindow, mSeq, mWindowAttributes,
getHostVisibility(), mDisplay.getDisplayId(),
mAttachInfo.mContentInsets, mAttachInfo.mStableInsets,
mAttachInfo.mOutsets, mInputChannel);
}
//
}
}
}
private void postCallbackDelayedInternal(int callbackType,
Object action, Object token, long delayMillis) {// scheduleTraversals() ,token Null,delayMills 0
synchronized (mLock) {
final long now = SystemClock.uptimeMillis();
final long dueTime = now + delayMillis;
mCallbackQueues[callbackType].addCallbackLocked(dueTime, action, token);
// CallbackRecord ,
if (dueTime <= now) {// delayMills 0,
scheduleFrameLocked(now);
} else {
Message msg = mHandler.obtainMessage(MSG_DO_SCHEDULE_CALLBACK, action);
msg.arg1 = callbackType;
msg.setAsynchronous(true);
mHandler.sendMessageAtTime(msg, dueTime);
}
}
}
doCallbacks(Choreographer.CALLBACK_TRAVERSAL, frameTimeNanos);
public void run(long frameTimeNanos) {
if (token == FRAME_CALLBACK_TOKEN) {
((FrameCallback)action).doFrame(frameTimeNanos);
} else {
((Runnable)action).run();
}
}