美文网首页
Java-WIndow和Activity和View

Java-WIndow和Activity和View

作者: 没有了遇见 | 来源:发表于2024-02-17 10:09 被阅读0次

    ActivityThread handleLaunchActivity() performLaunchActivity()--->activity.attach()

    1: 创建PhoneWindow 将xml加载到PhoneWindow的DecorView上
    attach(){
    //创建 PhoneWindow
    mWindow = new PhoneWindow(this, window, activityConfigCallback);

    }

    Activity -->setContentView(){
    (PhoneWindow)getWindow().setContentView(layoutResID);
    }

    创建PhoneWindow 创建DecorView 将xml加载到DecorView中
    PhoneWindow-->{

    setContentView(){
    //创建 DecorView
    installDecor(){
    //创建 DecorView
    mDecor = generateDecor(-1);
    //获取父类根布局
    mContentParent = generateLayout(mDecor){
    //加载 res传递过来的xml
    mDecor.onResourcesLoaded(mLayoutInflater, layoutResource);
    };
    };
    }
    }

    2:处理展示---> window.addView

    ActivityThread--->handleResumeActivity(){
    //执行Activity onResume
    重点:
    执行Activity onResume的时候 View还没加载到 Window上所以此时还获取不了控件宽高
    if (!performResumeActivity(r, finalStateRequest, reason)){};

    r.window = r.activity.getWindow();
    View decor = r.window.getDecorView();
    decor.setVisibility(View.INVISIBLE);
    //WindowManager WindowManagerImpl是WindowManager的实现类实质是到WindowManagerImpl
    WindowManagerImpl
    此对象实现了{@link ViewManager}接口,
    允许您将任何View子类添加为屏幕上的顶级窗口。
    定义了其他窗口管理器特定的布局参数,用于控制窗口的显示方式。
    它还实现了{@link WindowManager}接口,允许您控制连接到设备的显示。
    ViewManager wm = a.getWindowManager();

    WindowManager.LayoutParams l = r.window.getAttributes();
    a.mDecor = decor;

    //将decorview 加载的View 添加到屏幕上
    (WindowManagerImpl)wm.addView(decor, l);

    ]
    WindowManagerImpl
    此对象实现了{@link ViewManager}接口,
    允许您将任何View子类添加为屏幕上的顶级窗口。
    定义了其他窗口管理器特定的布局参数,用于控制窗口的显示方式。
    它还实现了{@link WindowManager}接口,允许您控制连接到设备的显示。
    WindowManagerImpl -->{
    @Override
    public void addView(@NonNull View view, @NonNull ViewGroup.LayoutParams params) {

        //view 是decorview   以及布局对象 mContext.getDisplay()是获取了一个屏幕对象 
        mGlobal.addView(view, params, mContext.getDisplay(), mParentWindow);
    }
    

    }

    为与任何特定上下文无关的操作提供与系统窗口管理器的低级通信
    WindowManagerGlobal-->{
    addView(){
    root = new ViewRootImpl(view.getContext(), display);
    root.setView(view, wparams, panelParentView);
    }
    }

    视图层次结构的顶部,实现视图和WindowManager之间所需的协议
    ViewRootImpl{
    //保证了绘制同步
    synchronized (this) {
    requestLayout();
    requestLayout 是刷新布局的操作,
    调用此方法后 ViewRootImpl 所关联的 View 也执行 measure -> layout -> draw 操作,
    确保在 View 被添加到 Window 上显示到屏幕之前,已经完成测量和绘制操作。

      // 将 window的内容显示到屏幕上
      res = mWindowSession.addToDisplay(mWindow, mSeq, mWindowAttributes,
                            getHostVisibility(), mDisplay.getDisplayId(), mWinFrame,
                            mAttachInfo.mContentInsets, mAttachInfo.mStableInsets,
                            mAttachInfo.mOutsets, mAttachInfo.mDisplayCutout, mInputChannel);
                            
                            
                            
    }
    

    }

    mWindowSession{
    mWindowSession = WindowManagerGlobal.getWindowSession();

       public static IWindowSession getWindowSession() {
        synchronized (WindowManagerGlobal.class) {
            if (sWindowSession == null) {
                try {
                    InputMethodManager imm = InputMethodManager.getInstance();
                    // windowManager  就是一个WindowManagerService 
                    IWindowManager windowManager = getWindowManagerService();
                    sWindowSession = windowManager.openSession(
                            new IWindowSessionCallback.Stub() {
                                @Override
                                public void onAnimatorScaleChanged(float scale) {
                                    ValueAnimator.setDurationScale(scale);
                                }
                            },
                            imm.getClient(), imm.getInputContext());
                } catch (RemoteException e) {
                    throw e.rethrowFromSystemServer();
                }
            }
            return sWindowSession;
        }
    }
    

    }

    WindowManagerService --->{
    openSession(){
    if (client == null) throw new IllegalArgumentException("null client");
    if (inputContext == null) throw new IllegalArgumentException("null inputContext");
    this 代表 WindowManagerService
    Session session = new Session(this, callback, client, inputContext);
    return session;
    }
    }

    mWindowSession.addToDisplay(){

    @Override
    public int addToDisplay(IWindow window, int seq, WindowManager.LayoutParams attrs,
            int viewVisibility, int displayId, Rect outFrame, Rect outContentInsets,
            Rect outStableInsets, Rect outOutsets,
            DisplayCutout.ParcelableWrapper outDisplayCutout, InputChannel outInputChannel) {
        return mService.addWindow(this, window, seq, attrs, viewVisibility, displayId, outFrame,
                outContentInsets, outStableInsets, outOutsets, outDisplayCutout, outInputChannel);
    }
    

    }

    又回到了WindowManagerService addWindow{

    final WindowState win = new WindowState(this, session, client, token, parentWindow,
                    appOp[0], seq, attrs, viewVisibility, session.mUid,
                    session.mCanAddInternalSystemWindow);
                    
                    
                     win.attach();
    

    }

    为什么win.attach()是创建与SurfaceFlinger通信的?简单了解下。
    跟踪下去是创建了SurfaceSession对象,这个创建进入native,最终创建了一个与SurfaceFlinger通信的 SurfaceComposerClient。 因此,可以与SurfaceFlinger进行通信。
    ViewRootImpl创建时 就创建的mSurface,mSurface是ViewRootImpl的成员变量,此时创建的Surface什么都没有,最后通过relayoutWindow()进入WMS 一步步向SurfaceFlinger发出请求。
    这时几处相关代码。
    WindowState{
    void attach() {
    if (localLOGV) Slog.v(TAG, "Attaching " + this + " token=" + mToken);
    mSession.windowAddedLocked(mAttrs.packageName);
    }

    }

    Session{

    void windowAddedLocked(String packageName) {
        mPackageName = packageName;
        mRelayoutTag = "relayoutWindow: " + mPackageName;
        if (mSurfaceSession == null) {
            if (WindowManagerService.localLOGV) Slog.v(
                TAG_WM, "First window added to " + this + ", creating SurfaceSession");
            mSurfaceSession = new SurfaceSession();
            if (SHOW_TRANSACTIONS) Slog.i(
                    TAG_WM, "  NEW SURFACE SESSION " + mSurfaceSession);
            mService.mSessions.add(this);
            if (mLastReportedAnimatorScale != mService.getCurrentAnimatorScale()) {
                mService.dispatchNewAnimatorScaleLocked(this);
            }
        }
        mNumWindow++;
    }
    

    }

    窗口管理核心类:DisplayContent,WindowToken和WindowState

    DisplayContent 理解为显示器 管理一个显示器上的各个窗口

    WindowState 窗口状态可以理解为一个窗口(各种状态)
    WindowToken 可以理解未WindowState 的集合
    WindowManager 窗口管理
    WindowMaangerService 窗口管理

    WindowManagerService 负责窗口(window)管理,窗口动画,输入法,Surface 管理

    -窗口管理: 负责窗口的启动,添加和删除,另外窗口的大小也时有 WMS 管理的,
    管理窗口的核心成员有DisplayContent,WindowToken 和 WindowState
    -窗口动画:窗口间进行切换时,使用窗口动画可以更好看一些,窗口动画由
    WMS 动画子系统来负责,动画的管理系统为 WindowAnimator
    -输入系统的中转站:通过对窗口触摸而产生的触摸事件,InputManagerServer(IMS) 会对触摸事件进行处理,他会寻找一个最合适的窗口来处理触摸反馈信息,
    WMS 是窗口的管理者,因此理所当然的就成为了输入系统的中转站
    -Surface管理:
    窗口并不具备绘制的功能,因此每个窗口都需要有一个块 Surface 来供自己绘制,为每个窗口分配 Surface 是由 WMS 来完成的。

    相关文章

      网友评论

          本文标题:Java-WIndow和Activity和View

          本文链接:https://www.haomeiwen.com/subject/xxwuadtx.html