Android WMS流程

WMS流程

Window & Activity & DecorView & ViewRoot关系

  • Activity:
    • 处理器,控制生命周期和处理事件
    • 1个Activity包含1个Window
    • 通过回调与Window、View交互
  • Window:
    • 实现类是PhoneWindow
    • 视图的承载器,用于管理View的显示
    • PhoneWindow内部包含一个DecorView
    • 内部通过WindowManager管理UI,将DecorView交给ViewRoot
  • DecorView:
    • 顶层View,本质是FrameLayout
    • 显示和加载布局
    • View的事件最先经过DecorView,再分发到子View
  • ViewRoot:
    • ViewRootImpl是其实现类
    • 用于连接WindowManagerDecorView
    • 完成View的三大流程:测量、布局、绘制

在这里插入图片描述

在这里插入图片描述

流程图

在这里插入图片描述

源码分析

ActivityThread#handleLaunchActivity()

  • 初始化WMS服务
  • 调用performLaunchActivity()
public Activity handleLaunchActivity(ActivityClientRecord r,
        PendingTransactionActions pendingActions, Intent customIntent) {
  
    //初始化WMS服务
    WindowManagerGlobal.initialize();
    
    //调用performLaunchActivity()初始化Activity
    final Activity a = performLaunchActivity(r, customIntent);

    return a;
}

ActivityThread#performLaunchActivity()

  • 创建Activity
  • 调用Activity#attach()
  • 回调Activity#onCreate()
private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
    Activity activity = null;
    try {
        //创建Activity
        java.lang.ClassLoader cl = appContext.getClassLoader();
        activity = mInstrumentation.newActivity(
            cl, component.getClassName(), r.intent);
    } catch (Exception e) {       
    }


    if (activity != null) {
        //调用Activity#attach(),初始化Activity
        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);


        //callActivityOnCreate()方法最终调用Activity#onCreate()
        activity.mCalled = false;
        if (r.isPersistable()) {
            mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);
        } else {
            mInstrumentation.callActivityOnCreate(activity, r.state);
        }
    }
    return activity;
}

Activity#attach()

  • 创建PhoneWindow对象,PhoneWindow是Window的实现类
  • 创建WindowManageImpl,WindowManageImpl是WindowManage的实现类
final void attach(Context context, ActivityThread aThread,
                  Instrumentation instr, IBinder token, int ident,
                  Application application, Intent intent, ActivityInfo info,
                  CharSequence title, Activity parent, String id,
                  NonConfigurationInstances lastNonConfigurationInstances,
                  Configuration config, String referrer, IVoiceInteractor voiceInteractor,
                  Window window, ActivityConfigCallback activityConfigCallback, 
                  IBinder assistToken) {
    
    attachBaseContext(context);

    //创建PhoneWindow
    mWindow = new PhoneWindow(this, window, activityConfigCallback);
    mWindow.setWindowControllerCallback(mWindowControllerCallback);
    mWindow.setCallback(this);
    mWindow.setOnWindowDismissedCallback(this);
    mWindow.getLayoutInflater().setPrivateFactory(this);

    //设置软键盘
    if (info.softInputMode != WindowManager.LayoutParams.SOFT_INPUT_STATE_UNSPECIFIED) {
        mWindow.setSoftInputMode(info.softInputMode);
    }

    //在Window#setWindowManager()中创建WindowManager
    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();
}

Activity#setContentView()

  • 最终调用PhoneWindow#setContentView()
@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
}

public void setContentView(@LayoutRes int layoutResID) {
    //最终调用PhoneWindow#setContentView()
    getWindow().setContentView(layoutResID);
    initWindowDecorActionBar();
}

PhoneWindow#setContentView()

  • 创建DecorView
  • 将Activity的XML布局加载到DecorView中
public void setContentView(int layoutResID) {
    /*
    mContentParent为DecorView里的内容栏
    当mContentParent==null时,会调用installDecor()创建一个DecorView;
    当mContentParent!=null时,会删除所有子View
    */
    if (mContentParent == null) {
        installDecor();
    } else if (!hasFeature(FEATURE_CONTENT_TRANSITIONS)) {
        mContentParent.removeAllViews();
    }

    //加载解析XML布局,并添加到mContentParent内容栏里
    mLayoutInflater.inflate(layoutResID, mContentParent);

    //内容发生变化通知回调
    final Callback cb = getCallback();
    if (cb != null && !isDestroyed()) {
        cb.onContentChanged();
    }
}

PhoneWindow#installDecor()

private void installDecor() {
    mForceDecorInstall = false;
    if (mDecor == null) {
        //创建DecorView
        mDecor = generateDecor(-1);
    } else {
        mDecor.setWindow(this);
    }
    if (mContentParent == null) {
        //为DecorView设置布局格式
        mContentParent = generateLayout(mDecor);
    }
}

//创建DecorView
protected DecorView generateDecor(int featureId) {
    return new DecorView(context, featureId, this, getAttributes());
}

//为DecorView设置布局格式
//DecorView本质是一个FrameLayout里面包含:TitleView和ContentView
protected ViewGroup generateLayout(DecorView decor) {
    //从主题文件中获取样式信息
    TypedArray a = getWindowStyle();
    //根据主题样式,加载窗口布局
    int layoutResource;
    int features = getLocalFeatures();
    //加载layoutResource
    View in = mLayoutInflater.inflate(layoutResource, null);

    //往DecorView中添加子View
    decor.addView(in, new ViewGroup.LayoutParams(MATCH_PARENT, MATCH_PARENT)); 
    mContentRoot = (ViewGroup) in;

    //这里获取的是mContentParent = 即为内容栏(content)对应的DecorView = FrameLayout子类
    ViewGroup contentParent = (ViewGroup)findViewById(ID_ANDROID_CONTENT); 
    return contentParent;
}

ActivityThread#handleResumeActivity()

  • 回调Activity#onResume()
  • 获取PhoneWindow和DecorView,将Activity与DecorView绑定
  • 调用WindowManageImpl#addView()将DecorView传入
public void handleResumeActivity(IBinder token, boolean finalStateRequest, 
                                 boolean isForward, String reason) {

    //最终会调用Activity#onResume()
    final ActivityClientRecord r = performResumeActivity(token, finalStateRequest, reason);

    final Activity a = r.activity;

    if (r.window == null && !a.mFinished && willBeVisible) {
        //获取PhoneWindow对象
        r.window = r.activity.getWindow();
        //获取DecorView对象
        View decor = r.window.getDecorView();
        
        //DecorView不可见
        decor.setVisibility(View.INVISIBLE);
        ViewManager wm = a.getWindowManager();
        WindowManager.LayoutParams l = r.window.getAttributes();
        
        //DecorView与Activity建立关联
        a.mDecor = decor;

        if (a.mVisibleFromClient) {
            if (!a.mWindowAdded