Android ViewRootImpl

一、ViewRootImpl介绍

ViewRootImpl 是 View 的最高层级,是所有 View 的根。ViewRootImpl 实现了 View 和 WindowManager 之间所需要的协议。ViewRootImpl 的创建过程是从 WindowManagerImpl 中开始的。View 的测量,布局,绘制以及上屏,都是从 ViewRootImpl 中开始的。因此ViewRootImpl关联的类和接口非常多:

二、ViewRootImpl相关类和接口

IWindowSession

IWindowSession是用于客户端和WindowManagerService之间进行窗口管理操作的接口,用于向WindowManagerService发送请求。

IWindowSession文件路径:

frameworks/base/core/java/android/view/IWindowSession.aidl

IWindowSession定义:

interface IWindowSession {}

包括以下常用方法:

int addToDisplay(IWindow window, in WindowManager.LayoutParams attrs, in int viewVisibility, in int layerStackId, in InsetsVisibilities requestedVisibilities, out InputChannel outInputChannel, out InsetsState insetsState, out InsetsSourceControl[] activeControls, out Rect attachedFrame, out float[] sizeCompatScale):将一个窗口添加到指定的显示器上。
void remove(IWindow window):从窗口中删除指定的窗口。
oneway void setInsets(IWindow window, int touchableInsets, in Rect contentInsets, in Rect visibleInsets, in Region touchableRegion);:设置窗口的插图。
oneway void prepareToReplaceWindows(IBinder appToken, boolean childrenOnly):准备开始移除旧窗口并添加新窗口。
int relayout(IWindow window, in WindowManager.LayoutParams attrs, int requestedWidth, int requestedHeight, int viewVisibility, int flags, int seq, int lastSyncSeqId, out ClientWindowFrames outFrames, out MergedConfiguration outMergedConfiguration, out SurfaceControl outSurfaceControl, out InsetsState insetsState, out InsetsSourceControl[] activeControls, out Bundle bundle);重新布局指定窗口,并返回新的布局参数。

IWindowSessionCallback

IWindowSessionCallback是用于WindowManagerService和客户端之间进行通信的接口,用户向客户端发送来自WindowManagerService的响应。

IWindowSessionCallback文件路径:

frameworks/base/core/java/android/view/IWindowSessionCallback.aidl

IWindowSessionCallback定义:

oneway interface IWindowSessionCallback ()

IWindowSessionCallback方法:

void onAnimatorScaleChanged(float scale);

ViewParent

ViewParent是一个接口,它代表了一个视图的父容器,即视图在布局中的直接父控件,每个视图都有一个父容器,通过getParent()方法可以获得它的父容器,ViewParent中提供了与子视图相关的方法,如添加、删除或更新子视图等操作。所有的ViewGroup都是ViewParent的直接子类,它实现了ViewParent的这些方法,以便管理它们的子视图。ViewRootImpl类实现了ViewRootImpl接口。

ViewParent文件路径:

frameworks/base/core/java/android/view/ViewParent.java

ViewParent定义:

public interface ViewParent {}

ViewParent接口包括如下方法:

public void requestLayout():当应用程序布局发生变化时,系统会自动调用ViewRootImpl中的requestLayout()方法,该方法会触发视图树的重新布局和绘制操作。
public boolean requestChildRectangleOnScreen(@NonNull View child, Rect rectangle, boolean immediate):当子视图需要在屏幕上显示时,会调用该方法请求父视图将子视图滚动到可见区域。
public ViewParent getParent():获取该视图的父视图,也就是ViewRootImpl。
public void invalidateChild(View child, Rect r):通知父视图要重新绘制子视图。
public ViewParent invalidateChildInParent(int[] location, Rect r):通知子视图要重新绘制。
public void bringChildToFront(View child):将指定的子视图移动到父视图的顶部。
public boolean canResolveTextAlignment():是否可以在布局结束前确定视图的文本对齐方式。
public boolean canResolveTextDirection():是否可以在布局结束前确定视图的文本方向。
public void childDrawableStateChanged(@NonNull View child):当子视图的可绘制状态发生变化时,通知其父视图
public boolean isLayoutRequested():Indicates whether layout was requested on this view parent.
public void requestTransparentRegion(View child):Called when a child wants the view hierarchy to gather and report transparent regions to the window compositor. 
public void requestChildFocus(View child, View focused):Called when a child of this parent wants focus
public void recomputeViewAttributes(View child):Tell view hierarchy that the global view attributes need to be re-evaluated.
public void clearChildFocus(View child):Called when a child of this parent is giving up focus
public boolean getChildVisibleRect(View child, Rect r, android.graphics.Point offset):Compute the visible part of a rectangular region defined in terms of a child view' s coordinates.
public View focusSearch(View v, int direction):Find the nearest view in the specified direction that wants to take focus
public void focusableViewAvailable(View v):Tells the parent that a new focusable view has become available. 
public boolean showContextMenuForChild(View originalView):Shows the context menu for the specified view or its ancestors.
public void createContextMenu(ContextMenu menu):Have the parent populate the specified context menu if it has anything to add (and then recurse on its parent).
public ActionMode startActionModeForChild(View originalView, ActionMode.Callback callback):Start an action mode for the specified view with the default type
public ActionMode startActionModeForChild(View originalView, ActionMode.Callback callback, int type):Start an action mode of a specific type for the specified view.
public void requestDisallowInterceptTouchEvent(boolean disallowIntercept):Called when a child does not want this parent and its ancestors to intercept touch events with {@link ViewGroup#onInterceptTouchEvent(MotionEvent)}.
public boolean requestSendAccessibilityEvent(@NonNull View child, AccessibilityEvent event):Called by a child to request from its parent to send an {@link AccessibilityEvent}.
public void childHasTransientStateChanged(@NonNull View child, boolean hasTransientState):Called when a child view now has or no longer is tracking transient state.
public void requestFitSystemWindows();Ask that a new dispatch of {@link View#fitSystemWindows(Rect) View.fitSystemWindows(Rect)} be performed.
public ViewParent getParentForAccessibility():Gets the parent of a given View for accessibility. 
public void notifySubtreeAccessibilityStateChanged(@NonNull View child, @NonNull View source, int changeType);Notifies a view parent that the accessibility state of one of its descendants has changed and that the structure of the subtree is different.
public boolean onStartNestedScroll(@NonNull View child, @NonNull View target, int nestedScrollAxes):React to a descendant view initiating a nestable scroll operation, claiming the nested scroll operation if appropriate.
public void onNestedScrollAccepted(@NonNull View child, @NonNull View target, int nestedScrollAxes);React to the successful claiming of a nested scroll operation.
public void onStopNestedScroll(@NonNull View target):React to a nested scroll operation ending.
public void onNestedScroll(@NonNull View target, int dxConsumed, int dyConsumed, int dxUnconsumed, int dyUnconsumed):React to a nested scroll in progress.
public void onNestedPreScroll(@NonNull View target, int dx, int dy, @NonNull int[] consumed):React to a nested scroll in progress before the target view consumes a portion of the scroll.
public boolean onNestedFling(@NonNull View target, float velocityX, float velocityY, boolean consumed):Request a fling from a nested scroll.
public boolean onNestedPreFling(@NonNull View target, float velocityX, float velocityY):React to a nested fling before the target view consumes it.
public boolean onNestedPrePerformAccessibilityAction(@NonNull View target, int action, @Nullable Bundle arguments):React to an accessibility action delegated by a target descendant view before the target processes it.

ViewManange

ViewManager是表示View系统的管理器,用于管理应用曾向的视图层次结构。视图层次结构是一组嵌套的视图,由视图(View)和视图组(ViewGroup)组成。

ViewManager负责处理应用程序中包括Activity的视图布局,包括添加、删除和更新视图等操作。

WindowManager实现了ViewManager接口。

ViewManager文件路径:

frameworks/base/core/java/android/view/ViewManager.java

ViewManager定义:

public interface ViewManager {}

ViewManager是一个接口,定义了三个方法:

public void addView(View view,ViewGroup.LayoutParams params):添加一个视图到指定的视图组中。
public void updateViewLayout(View view,ViewGroup.LayoutParams params):更新视图在层次结构中的布局参数。
public void removeView(View view):从视图层次结构中删除指定的视图。

SurfaceHolder

SurfaceHolder是Android系统提供的一个用于控制Surface的接口,它允许应用程序获取到Canvas对象,并在Surface上作画,具体来说,SurfaceHolder通过SurfaceView以及底层的Surface对象允许开发者直接控制显示在屏幕上的像素,SurfaceHolder内部维护了一个用于显示渲染图像的Canvas对象,应用程序可以获取到该对象,并通过器绘制图像。如果应用程序更新了绘制内容,CanVas对象就会像Surface对象中填充响应的像素数据,即实现了内容的绘制和更新,

另外,SurfaceHolder还提供了一些控制Surface的方法,

addCallback(Callback callback):添加回调接口,用于在Surface此次发生改变、Surface被销毁等事件发生时进行回调。

setFixedSize(int width, int heignt):设置Surface的大小。

setFormat(int format):设置Surface的像素格式。

setType(int type):设置Surface的格式。

SurfaceHolder文件路径:

frameworks/base/core/java/android/view/SurfaceHolder.java

SurfaceHolder定义:

public interface SurfaceHolder {
    public static class BadSurfaceTypeException extends RuntimeException {}
    public interface Callback {}
    public interface Callback2 extends Callback {}
}

Surface

在Android系统中,每个Activity都对应一个Window,一个Window对应一个Surface,可以说每个Activity都对应一个Surface,当一个Activity启动时,系统会为其创建一个Window对象,而Window对象中除了包含Decorview等视图之外,还包括一个Surface对象。

Surface是Android中用于表示一个图像缓冲区的类,在View系统的绘制显示过程中VIewRootImpl会首先创建一个Surface作为绘制目标,并将器床底给DecorView,即该Activity的顶层View。然后,View系统会在Surface上进行绘制,并将绘制结果更新到Surface上。最后,SurfaceFlinger系统服务会将Surface中的渲染结果交给GPU进行处理,然后输出到显示器上,完成最终显示,Surface的作用包括:

1、显示视图内容:当应用程序需要在屏幕上渲染自定义视图时,可以通过Surface实现。应用程序在视图上绘画时,会直接将绘制结果提交到Surface所在的缓冲区中,从而实现视图的显示。

2、OpenGL ES渲染:当应用程序需要在屏幕上进行OpenGL ES渲染时,可以通过Surface实现。应用程序将渲染结果提交到Surface所在缓存区中,从而实现OpenGL ES的渲染。

3、视频处理:在应用程序中进行视频处理时,可以利用Surface将视频数据渲染到屏幕上,从而实现视频的播放和处理。

4、屏幕截图和录屏:通过使用Surface,可以从系统中抓取屏幕图像数据,从而实现屏幕截图,此外,还可以通过使用Surface在屏幕上绘制图像内容,实现屏幕录制。

Surface文件路径:

frameworks/base/core/java/android/view/Surface.java

Surface定义:

public class Surface implements Parcelable {
    private final class CompatibleCanvas extends Canvas {}
    private final class HwuiContext {}
}

SurfaceControl

SurfaceControl是Android系统中的一个类,用于管理和控制Surface的创建、显示和销毁。它提供了一系列方法来操作Surface,包括创建Surface、设置Surface的属性和位置、更新Surface的内容等。

SurfaceControl文件路径:

frameworks/base/core/java/android/view/SurfaceControl.java

SurfaceControl定义:

public final class SurfaceControl implements Parcelable {}

SurfaceSession

SurfaceSession是Android系统中的一个类,用于管理和控制窗口的显示和交互。它提供了与窗口相关的功能,例如创建、删除和管理窗口,以及处理窗口的事件和动画。

SurfaceSession文件路径:

frameworks/base/core/java/android/view/SurfaceSession.java

SurfaceSession定义:

public final class SurfaceSession {}

ViewRootImpl

ViewRootImpl是Android视图根布局的实现类,属于所有View的根(但ViewRootImpl不是View,只是实现了ViewParent接口),是Android实现视图层级管理的核心部分。每个Activity对应一个ViewRootImpl,用于管理窗口的布局、事件的响应和刷新等工作,ViewRootImpl负责以下工作:

1、响应用户事件,如触摸、按键等,将其分发给视图树中的对应View进行处理。

2、监听布局变化,当视图发生变化时,重新计算尺寸、位置等布局信息,进行页面的重新绘制。

3、控制动画效果,实现布局的渐变、平移、缩放等动画效果。

4、处理Activity的生命周期,实现布局的渐变、平移、缩放等动画效果。

ViewRootImpl文件路径:

frameworks/base/core/java/android/view/ViewRootImpl.java

ViewRootImpl定义:

public final class ViewRootImpl implements ViewParent,
        View.AttachInfo.Callbacks, ThreadedRenderer.DrawCallbacks,
        AttachedSurfaceControl {
    public interface ConfigChangedCallback {}
    public interface ActivityConfigCallback {}
    static final class SystemUiVisibilityInfo {}
    public interface SurfaceChangedCallback {}
    final class ViewRootHandler extends Handler {}
    abstract class InputStage {}
    abstract class AsyncInputStage extends InputStage {}
    final class NativePreImeInputStage extends AsyncInputStage implements InputQueue.FinishedInputEventCallback {}
    final class ViewPreImeInputStage extends InputStage {
    final class ImeInputStage extends AsyncInputStage implements InputMethodManager.FinishedInputEventCallback {}
    final class EarlyPostImeInputStage extends InputStage {}
    final class NativePostImeInputStage extends AsyncInputStage implements InputQueue.FinishedInputEventCallback {}
    final class ViewPostImeInputStage extends InputStage {}
    final class SyntheticInputStage extends InputStage {}
    final class SyntheticTrackballHandler {}
    static final class TrackballAxis {}
    final class SyntheticJoystickHandler extends Handler {}
    final class SyntheticTouchNavigationHandler extends Handler {}
    final class SyntheticKeyboardHandler {}
    static final class GfxInfo {}
    private static final class QueuedInputEvent {}
    final class TraversalRunnable implements Runnable {}
    final class WindowInputEventReceiver extends InputEventReceiver {}
    final class InputMetricsListener implements HardwareRendererObserver.OnFrameMetricsAvailableListener {}
    final class ConsumeBatchedInputRunnable implements Runnable {}
    final class ConsumeBatchedInputImmediatelyRunnable implements Runnable {}
    final class InvalidateOnAnimationRunnable implements Runnable {}
    class TakenSurfaceHolder extends BaseSurfaceHolder {}
    static class W extends IWindow.Stub {}
    public static final class CalledFromWrongThreadException extends AndroidRuntimeException {}
    final class HighContrastTextManager implements HighTextContrastChangeListener {}
    static final class AccessibilityInteractionConnection extends IAccessibilityInteractionConnection.Stub {}
    private class SendWindowContentChangedAccessibilityEvent implements Runnable {}
    private static class UnhandledKeyManager {}
}

ViewRootImpl方法:

void scheduleTraversals():用于调度视图的遍历和绘制过程。在该方法中,首先通过调用postSyncBarrier()方法发送一个同步屏障,以确保后续的同步消息在视图绘制完成之前不会执行。然后,通过发送异步消息来触发视图的遍历和绘制过程。
void unscheduleTraversals() :用于取消调度视图遍历的操作。当系统完成UI视图的渲染刷新后,会调用unscheduleTraversals方法来移除同步屏障,并取消之前调度的遍历操作。

Session

wm.Session是Android系统中一个系统级别的服务组件,它负责管理和维护应用程序与系统窗口之间的通信和协作。wm.Session通常是在WindowManagerService组件中实现的,wm.Session提供了一系列接口,用于创建、更新、销毁窗口,以及获取窗口的位置、大小、状态等信息:

  • addToDisplay():将一个VIew添加到指定的Display中

  • remoe():从此Session中删除所有窗口并结束会话。

  • updateSurfacePosition():在此Session中更新SurfaceControl位置。

  • updateSurfaceSize():在此Session中更新SurfaceControl的大小。

  • relayout():重新布局一个窗口。

Session代码位于:

frameworks/base/service/java/com/android/server/wm/Session.java

wm.Session的定义:

public final class Session extends IWindowSession.Stub 
implements IBinder.DeathRecipient{}

三、ViewRootImpl与其他类的关系

1、ViewRootImpl与WindowManagerGlobal的关系

ViewRootImpl由WindowManager的本地单例类WindowManagerGlobal创建。WindowManagerGlobal在其内部存储着ViewRootImpl和View实例的映射关系。

public final class WindowManagerGlobal {
    /*******部分代码省略**********/
    //所有Window对象中的View
    private final ArrayList<View> mViews = new ArrayList<View>();
    //所有Window对象中的View所对应的ViewRootImpl
    private final ArrayList<ViewRootImpl> mRoots = new ArrayList<ViewRootImpl>();
    //所有Window对象中的View所对应的布局参数
    private final ArrayList<WindowManager.LayoutParams> mParams = new ArrayList<WindowManager.LayoutParams>();
    /*******部分代码省略**********/
}

2、ViewRootImpl与Window的关系

ViewRootImpl与Window之间没有直接的接口,它们是通过WindowManager进行关联的,在Android应用程序中,当需要显示一个新窗口是,通常先会创建一个Windwo对象,并将其与WindowManager进行关联。

3、ViewRootImpl与View(DecorView)的关系

当一个Activity实例创建时,它会创建自己的DecorView,并使用setContentView()方法设置该视图作为视图层级结构的根节点。在此过程中,ViewRootImpl实例会被创建出来,同时将DecorView作为参数传递进去。这样,ViewRootImpl对象就可以通过DecorView对象来管理整个应用程序的视图层级结构了,来实现界面的绘制、事件分发等操作。

但要注意的时,ViewRootImpl实例并不是只能管理DecorView,实际上,它可以管理任意类型的视图对象,只不过在大多数情况下,DecorView被用作整个应用程序视图层级结构的根节点,在应用程序开发过程中,需要根据实际情况来确定传递给ViewRootImpl构造函数的参数对象类型。

ViewRootImpl类实现了ViewParent接口,可以对视图层次结构的布局、绘制、子视图的添加和删除,以及处理触摸事件等操作进行控制和管理。

4、ViewRootImpl与WindowManagerService的关系

ViewRootImpl与WindowManagerService之间的关系是一种客户端与服务端自建的交互关系,ViewRootImpl作为客户端向其提供服务的WindowManagerService发出请求,以便实现对窗口的管理。

在Android应用程序中,每一个窗口都需要有一个对应的ViweRootImpl实例来管理它的视图层级结构,当一个窗口需要被创建或者已经创建后需要被更新,ViewRootImpl会通过它所维护的IWindowSession接口向WindowManagerService发送请求,以便创建或更新相应的窗口。

WindowManagerService是整个Android应用程序中用于管理所有窗口的服务,并提供了多种方法,用于管理窗口的生命周期,包括创建、更新和销毁等操作。当WindowManagerService收到来自ViewRootImpl发送的请求时,它会根据请求所包含的参数以及系统当前状态,调用相应的方法来完成相关的操作。

ViewRootImpl和WindowManagerService之间的交互是一种基于Binder IPC机制的进程间通信方式,通过IWindowSession接口传递参数和请求信息,在请求处理完成后,WindowManagerService会通过IWindowSessionCallback返回处理结果,以便ViewRootImpl可以更新相应的视图层级结构。

5、ViewRootImpl与Surface的关系

ViewRootImpl于Surface主要通过SurfaceView和SurfaceHolder接口来实现的,当应用程序中的View被使用SurfaceView方式展示时,ViewRootImpl会创建一个SurfaceHolder.Callback对象,并通过它获取到对应的Surface对象,然后ViewRootImpl将利用Surface对象中的lockCanvas方法获取Canvas对象,从而可以在上面进行视图鄂绘制操作,当视图内容需要更新时,VIewRootImpl会将更新后的Canvas对象提交给Surface,从而将更改后的内容显示到屏幕上。

此外ViewRootImpl中也包括对Surface和SuraceView的管理和控制,比如可以通过SurfaceHolder接口实现对Surface尺寸和旋转角度的控制,从而保证视图的正确显示。

6、ViewRootImpl与DisplayManager的关系

ViewRootImpl需要通过DisplayManager来获取当前设备上的所有显示设备对象,并根据这些设备的属性来对UI界面进行渲染和布局计算,ViewRootImpl会通过调用DispalyManager.getDisplay()方法来获取当前设备上的所有显示设备对象,然后选择其中于当前UI界面显示相关的设备进行渲染。例如,在多个物理显示器的情况下,ViewRootImpl需要根据当前UI界面的显示位置和大小来选择对应的物理显示器进行渲染。

7、ViewRootImpl与Input系统的关系

输入系统是Android系统中用于处理各种用于输入事件(如触摸、按键灯)的组件,而ViewRootImpl则是View系统中用于协调和分发输入事件的核心类。当一个用户输入事件发生时(如点击屏幕、滑动屏幕等),Input系统会将该事件封装成一个InputEvent对象,并将其发送到当前屏幕显示的顶层应用的ViewRootImpl对象,然后,ViewRootImpl会将该事件先传递到顶层的Window中的DecorView,最终传递给UI组件(如Button、TextView等)。

在ViewRootImpl的传递过程中,会进行事件的分发和过滤等操作,以便确保事件传递到正确的目标界面,同时,还需要考虑和处理多个接受同样输入的UI组件之间的优先级和关系。

  • 15
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值