joshuayingwhat IT Engineer

二:decorview加载

2024-08-06

当系统调用启动一个activity是就会通过反射启动,然后调用handlelauncheractivity。在handlelauncheracitiviy中执行mInstrumentation.callActivityOnCreate调用activity的oncrreate,并且调用activity.attach函数创建窗口视图phonewindow。

 private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
        ActivityInfo aInfo = r.activityInfo;
                activity.attach(activityBaseContext, 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.activityConfigCallback,
                        r.assistToken, r.shareableActivityToken, r.initialCallerInfoAccessToken);
                r.activity = activity;
                if (r.isPersistable()) {
                    mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);
                } else {
                    mInstrumentation.callActivityOnCreate(activity, r.state);
                }
            }
            r.setState(ON_CREATE);
       
        return activity;
    }

……

activity中oncreate的setcontentview函数就会被调用这个时候系统就会初始化decorview并且解析xml

public void setContentView(@LayoutRes int layoutResID) {
        getWindow().setContentView(layoutResID);
        initWindowDecorActionBar();
    }

其中getwidnow其实就是activiy.attach中创建的phonewindow。

public void setContentView(int layoutResID) {
        if (mContentParent == null) {
            installDecor();
        } else {
            mContentParent.removeAllViews();
        }
        mLayoutInflater.inflate(layoutResID, mContentParent);
        final Callback cb = getCallback();
        if (cb != null && !isDestroyed()) {
            cb.onContentChanged();
        }
    }

mContentParent就是app中的xml布局的父布局,在installdecor中初始化出来。installdecor主要做两件事一个是创建decorview第二个就是找到decorview中的容器mContentparent

private void installDecor() {
        if (mDecor == null) {
            mDecor = generateDecor();
            mDecor.setDescendantFocusability(ViewGroup.FOCUS_AFTER_DESCENDANTS);
            mDecor.setIsRootNamespace(true);
        }
        if (mContentParent == null) {
            mContentParent = generateLayout(mDecor);
        }
    }

protected DecorView generateDecor() {
        return new DecorView(getContext(), -1);
    }

generateDecor就是new Decorview,创建decorview对象。generateLayout将创建出来的mDecorview作为参数.

protected ViewGroup generateLayout(DecorView decor) {
        mDecor.startChanging();
        View in = mLayoutInflater.inflate(layoutResource, null);
        decor.addView(in, new ViewGroup.LayoutParams(MATCH_PARENT, MATCH_PARENT));
        ViewGroup contentParent = (ViewGroup)findViewById(ID_ANDROID_CONTENT);
        if (contentParent == null) {
            throw new RuntimeException("Window couldn't find content container view");
        }
        mDecor.finishChanging();
        return contentParent;
    }

其中ID_ANDROID_CONTENT就是decorview中的一个布局id。接下来解析布局mLayoutInflater.inflate(layoutResID, mContentParent);

 public View inflate(XmlPullParser parser, @Nullable ViewGroup root, boolean attachToRoot) {
        synchronized (mConstructorArgs) {
            View result = root;
            if (root != null && root.getViewRootImpl() != null) {
                root.getViewRootImpl().notifyRendererOfExpensiveFrame();
            }
                    if (root != null && attachToRoot) {
                        root.addView(temp, params);
                    }
                    if (root == null || !attachToRoot) {
                        result = temp;
                    }
                }
            return result;
        }
    }

root就是传进来的mCotnentParent。最终将我们的xml布局添加到decorview的布局中。最终decorview已经有布局内容了,接下来执行handleresumactiviy中的makevisible函数

void makeVisible() {
        if (!mWindowAdded) {
            ViewManager wm = getWindowManager();
            wm.addView(mDecor, getWindow().getAttributes());
            mWindowAdded = true;
        }
        mDecor.setVisibility(View.VISIBLE);
    }

最总调用windowmanager的addview方法。将我们的decorview添加到创建出来的phonewindow中。

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


Similar Posts

Content