joshuayingwhat IT Engineer

一:图形window加载视图

2024-08-01

window的初始化

activity加载视图,就相当于是一个容器一样。activitythread中启动activity时调用attach

 private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
	 activity.attach(appContext, this, getInstrumentation(), r.token,
                          r.ident, app, r.intent, r.activityInfo, title, r.parent,
                         r.embeddedID, r.lastNonConfigurationInstances, config,
                          r.referrer, r.voiceInteractor, window, r.configCallback,                          r.assistToken);
 }
 
 final void attach(Context context, ActivityThread aThread,...) {
		  mWindow = new PhoneWindow(this, window, activityConfigCallback);
		  mWindow.setCallback(this);
		  mWindow.setWindowManager(
                (WindowManager)context.getSystemService(Context.WINDOW_SERVICE),
                mToken, mComponent.flattenToString(),
                (info.flags & ActivityInfo.FLAG_HARDWARE_ACCELERATED) != 0);
      mWindowManager = mWindow.getWindowManager();
 }

……

这个时候就会创建一个window。从代码中可以看出一个activity只有一个window和一个windowmanager,并且设置windowmanager以及window的setcallback 键盘事件和触摸事件

window添加view过程

window主要是管理view的增删改的操作。activity启动后调用handleresumeactivity.

public void handleResumeActivity(ActivityClientRecord r, boolean finalStateRequest,
            boolean isForward, boolean shouldSendCompatFakeFocus, String reason) {
        final Activity a = r.activity;
        if (localLOGV) {
            Slog.v(TAG, "Resume " + r + " started activity: " + a.mStartedActivity
                    + ", hideForNow: " + r.hideForNow + ", finished: " + a.mFinished);
        }
       
        if (r.window == null && !a.mFinished && willBeVisible) {
            r.window = r.activity.getWindow();
            View decor = r.window.getDecorView();
            decor.setVisibility(View.INVISIBLE);
            ViewManager wm = a.getWindowManager();
            WindowManager.LayoutParams l = r.window.getAttributes();
            a.mDecor = decor;
            l.type = WindowManager.LayoutParams.TYPE_BASE_APPLICATION;
       
            if (a.mVisibleFromClient) {
                if (!a.mWindowAdded) {
                    a.mWindowAdded = true;
                    wm.addView(decor, l);
                } else {
                    // The activity will get a callback for this {@link LayoutParams} change
                    // earlier. However, at that time the decor will not be set (this is set
                    // in this method), so no action will be taken. This call ensures the
                    // callback occurs with the decor set.
                    a.onWindowAttributesChanged(l);
                }
            }
            // If the window has already been added, but during resume
            // we started another activity, then don't yet make the
            // window visible.
        } else if (!willBeVisible) {
            if (localLOGV) Slog.v(TAG, "Launch " + r + " mStartedActivity set");
            r.hideForNow = true;
        }
       
            if (r.activity.mVisibleFromClient) {
                r.activity.makeVisible();
            }
    }

wm.addview就是将decorview 通过windowmanager(wm就是windowmanagerimpl)调用addview

@Override
    public void addView(@NonNull View view, @NonNull ViewGroup.LayoutParams params) {
        applyTokens(params);
        mGlobal.addView(view, params, mContext.getDisplayNoVerify(), mParentWindow,
                mContext.getUserId());
    }

最终又是调用到了mglobal中的addview。mglobal就是windowmanagerglobal 在windowmanagerimpl中通过单利初始化windowmanagerglobal(private final WindowManagerGlobal mGlobal = WindowManagerGlobal.getInstance();)因此每个进程只有一个实例

public void addView(View view, ViewGroup.LayoutParams params,
            Display display, Window parentWindow) {
        final WindowManager.LayoutParams wparams = (WindowManager.LayoutParams)params;
        if (parentWindow != null) {
            parentWindow.adjustLayoutParamsForSubWindow(wparams);
        } else {
            // If there's no parent and we're running on L or above (or in the
            // system context), assume we want hardware acceleration.
            final Context context = view.getContext();
            if (context != null
                    && context.getApplicationInfo().targetSdkVersion >= Build.VERSION_CODES.LOLLIPOP) {
                wparams.flags |= WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED;
            }
        }
        ViewRootImpl root;
        View panelParentView = null;
        root = new ViewRootImpl(view.getContext(), display);
        view.setLayoutParams(wparams);
        mViews.add(view);
        mRoots.add(root);
        mParams.add(wparams);
        }
        // do this last because it fires off messages to start doing things
        try {
            root.setView(view, wparams, panelParentView);
        } catch (RuntimeException e) {
            throw e;
        }
    }

addview时会创建一个viewrootimpl对象调用这个对象的setview。也就是每次addview的时候都会创建一个viewrootimpl的实例。再viewrootimpl中调用session通过binder通信将客户端的请求发送给wsm

 public void setView(View view, WindowManager.LayoutParams attrs, View panelParentView,
            int userId) {
				 res = mWindowSession.addToDisplayAsUser(mWindow, mWindowAttributes,
                            getHostVisibility(), mDisplay.getDisplayId(), userId,
                            mInsetsController.getRequestedVisibleTypes(), inputChannel, mTempInsets,
                            mTempControls, attachedFrame, compatScale);	            
 }

mwindowsession是再客户端的代理一样通过调用session的addTodisplayAsUser最终会调用到wms中的addWindow 其中mService就是wms。

参考: [https://www.jianshu.com/p/b3a1ea7923e7]


Similar Posts

Content