(As well as the relationship between the Activity ActivityThread Window WindowManager viewRootImpl View) to start the process of Activity

ActivityThread entry procedure is, in its main function,

  1. Looper initialization, and open loop function, and a new instance of itself, called attach method, as part of the code
Looper.prepareMainLooper();
ActivityThread thread = new ActivityThread();
thread.attach(false, startSeq);
Looper.loop();

Before you create a new Activity, it will first initialize the application (if not present).
Activity in the process of creating, the first call
scheduleLaunchActivity()
after they call
handleLaunchActivity()

private void handleLaunchActivity(ActivityClientRecord r, Intent customIntent) {
    handleConfigurationChanged(null, null);
    //初始化 WindowManagerService,主要是获取到 WindowManagerService 代理对象
    WindowManagerGlobal.initialize();
    //初始化Activity
    Activity a = performLaunchActivity(r, customIntent);

    if (a != null) {
        r.createdConfig = new Configuration(mConfiguration);
        //显示布局
        handleResumeActivity(r.token, false, r.isForward,
                !r.activity.mFinished && !r.startsNotResumed);
       
    }
}

In performLaunchActivity method, a new activity will example out method and performs attach

Activity activity = null;
try {
    java.lang.ClassLoader cl = appContext.getClassLoader();
    activity = mInstrumentation.newActivity(
            cl, component.getClassName(), r.intent);
    StrictMode.incrementExpectedActivityCount(activity.getClass());
    r.intent.setExtrasClassLoader(cl);
    r.intent.prepareToEnterProcess();
    if (r.state != null) {
        r.state.setClassLoader(cl);
    }
} catch (Exception e) {
    if (!mInstrumentation.onException(activity, e)) {
        throw new RuntimeException(
            "Unable to instantiate activity " + component
            + ": " + e.toString(), e);
    }
}
......
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);

Activity.attach method initializes the window,

mWindow = new PhoneWindow(this, window, activityConfigCallback);
mWindow.setWindowManager(
	(WindowManager)context.getSystemService(Context.WINDOW_SERVICE),
	mToken, mComponent.flattenToString(),
	(info.flags & ActivityInfo.FLAG_HARDWARE_ACCELERATED) != 0);
if (mParent != null) {
    mWindow.setContainer(mParent.getWindow());
}
mWindowManager = mWindow.getWindowManager();

window is an abstract class, is a specific implementation PhoneWindow, Android in activity or whether Dialog, are used in phoneWindow. At the same time give a WindowManager objects, WindowManager is an abstract class, particularly to achieve this is to WindowManagerImpl the WindowManager

public void setWindowManager(WindowManager wm, IBinder appToken, String appName, boolean hardwareAccelerated) {
    mWindowManager = ((WindowManagerImpl)wm).createLocalWindowManager(this);
}

Each Activity will have a WindowManager object, and this is mWindowManager and WindowManagerService communicate, but also WindowManagerService specific key that identifies View Activity belong incoming IBinder type of mToken time of creation.

After performing these, over activity on the implementation of the attach method, and then return to performLaunchActivity process continues,

if (r.isPersistable()) {
	mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);
} else {
	mInstrumentation.callActivityOnCreate(activity, r.state);
}

This method onCreate method callback activity, usually in onCreate we set contentView,
the layout settings to the activity, in fact, just this time to call a window to set the layout window:
Activity.setContentView ():

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

PhoneWindow.setContentView():

public void setContentView(int layoutResID) {
    ...    
    installDecor(); 
    ... 
}

installDecor method initializes DectorView and mContentParent, mContentParent view DecorView the sub.
Then just created PhoneWindow, and DecorView, but the two do not have any relationship, the relationship is generated in ActivityThread.performResumeActivity, and then call r.activity.performResume (), call r.activity.makeVisible, will add to the current DecorView the Window.

Thus Activity.onCreate the method finishes, ActivityThread the performLaunchActivity handleLaunchActivity logically and substantially executed.
Under Summary: initialized Activity, Activity initialized to the window, WindowManager. Window is initialized DecorView

And performs ActivityThread.handleStartActivity performStartActivity After executing both these methods, the corresponding method is executed Activity.onStart. These do not involve the UI part, I will not go into details.

Then, on to the handleResumeActivity,

final void handleResumeActivity(IBinder token, boolean clearHide, boolean isForward, boolean reallyResume) {
    //执行到 onResume()
    ActivityClientRecord r = performResumeActivity(token, clearHide);

    if (r != null) {
        final Activity a = r.activity;
        boolean willBeVisible = !a.mStartedActivity;
        ...
        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;
            l.softInputMode |= forwardBit;
            if (a.mVisibleFromClient) {
                a.mWindowAdded = true;
                wm.addView(decor, l);
            }

        }
        ...
        if (!r.activity.mFinished && willBeVisible
                && r.activity.mDecor != null && !r.hideForNow) {
            ...
            mNumVisibleActivities++;
            if (r.activity.mVisibleFromClient) {
                //添加视图,详见下面分析
                r.activity.makeVisible(); 
            }
        }

        //resume 完成
        if (reallyResume) {
              ActivityManagerNative.getDefault().activityResumed(token);
        }
    } else {
        ...
    }
}

Activity.makeVisible():

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

In this method calls performResumeActivity, performResumeActivity callback Activity.onResume.
In which of these methods, it is first of dector Activity points DectorView window, and
then added via WindowManager. WindowManager of addView concrete realization in WindowManagerImpl, whereas WindowManagerImpl of addView will call WindowManagerGlobal.addView ().

WindowManagerGlobal.addView():

public void addView(View view, ViewGroup.LayoutParams params,Display display, Window parentWindow) {
    ...
    ViewRootImpl root = new ViewRootImpl(view.getContext(), display);        
    view.setLayoutParams(wparams);    
    mViews.add(view);    
    mRoots.add(root);    
    mParams.add(wparams);        
    root.setView(view, wparams, panelParentView);
    ...
}

This process creates a ViewRootImpl, and previously created DecoView as a parameter, after DecoView event by ViewRootImpl to manage, for example, add the DecoView View, Delete View.

ViewRootImpl realized ViewParent this interface. General view of his parent container layout, DecorView the parent is ViewRootImpl, in

    root.setView(view, wparams, panelParentView);

This method of execution, carried out parent binding ViewRootImpl.

After execution, the display on the screen by other means.

Published 17 original articles · won praise 12 · views 10000 +

Guess you like

Origin blog.csdn.net/qq_24295537/article/details/104984116