WindowManager addView

首先WindowManager是怎么获取的

WindowManager mWindowManager = Context.getSystemService(WindowManager.class);

可以通过这种方式给Activity add一个view
接着找到WindowManager和其他两个类的关系

public final class WindowManagerImpl implements WindowManager {
public interface WindowManager extends ViewManager {
public interface ViewManager

3个类的路径

frameworks/base/core/java/android/view/WindowManager.java
frameworks/base/core/java/android/view/ViewManager.java
frameworks/base/core/java/android/view/WindowManagerImpl.java

先看ViewManager的内容,比较简单

package android.view;

/** Interface to let you add and remove child views to an Activity. To get an instance
  * of this class, call {@link android.content.Context#getSystemService(java.lang.String) Context.getSystemService()}.
  */
public interface ViewManager
{
    /**
     * Assign the passed LayoutParams to the passed View and add the view to the window.
     * <p>Throws {@link android.view.WindowManager.BadTokenException} for certain programming
     * errors, such as adding a second view to a window without removing the first view.
     * <p>Throws {@link android.view.WindowManager.InvalidDisplayException} if the window is on a
     * secondary {@link Display} and the specified display can't be found
     * (see {@link android.app.Presentation}).
     * @param view The view to be added to this window.
     * @param params The LayoutParams to assign to view.
     */
    public void addView(View view, ViewGroup.LayoutParams params);
    public void updateViewLayout(View view, ViewGroup.LayoutParams params);
    public void removeView(View view);
}

从上面的注释可以看出
WindowManager mWindowManager = Context.getSystemService(WindowManager.class);
可以通过这种方式给Activity add一个view

WindowManagerImpl实现了WindowManager
所以addView方法也是在这里实现的

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

mGlobal是什么

private final WindowManagerGlobal mGlobal = WindowManagerGlobal.getInstance();

WindowManagerGlobal路径

frameworks/base/core/java/android/view/WindowManagerGlobal.java

真正的addView的实现是在这里

public void addView(View view, ViewGroup.LayoutParams params,
        Display display, Window parentWindow) {
        ...
        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) {
... 
}

也就是说会new一个ViewRootImpl
3个关键变量
mViews
mRoots
mParams

至于ViewRootImpl创建过程不再这里说明

这里还有一点疑问

mGlobal.addView(view, params, mContext.getDisplay(), mParentWindow);

这句代码中mParentWindow是哪来的
其实是创建WindowManagerImpl的时候传递进来的

    private WindowManagerImpl(Context context, Window parentWindow) {
        mContext = context;
        mParentWindow = parentWindow;
    }

    public WindowManagerImpl createLocalWindowManager(Window parentWindow) {
        return new WindowManagerImpl(mContext, parentWindow);
    }

而createLocalWindowManager是在Window.java的setWindowManager函数中调用的

Window.java路径

frameworks/base/core/java/android/view/Window.java

setWindowManager的实现

    /**
     * Set the window manager for use by this Window to, for example,
     * display panels.  This is <em>not</em> used for displaying the
     * Window itself -- that must be done by the client.
     *
     * @param wm The window manager for adding new windows.
     */
    public void setWindowManager(WindowManager wm, IBinder appToken, String appName,
            boolean hardwareAccelerated) {
        mAppToken = appToken;
        mAppName = appName;
        mHardwareAccelerated = hardwareAccelerated
                || SystemProperties.getBoolean(PROPERTY_HARDWARE_UI, false);
        if (wm == null) {
            wm = (WindowManager)mContext.getSystemService(Context.WINDOW_SERVICE);
        }
        mWindowManager = ((WindowManagerImpl)wm).createLocalWindowManager(this);
    }

再来看一下Window.java这个类的注释

/**
 * Abstract base class for a top-level window look and behavior policy.  An
 * instance of this class should be used as the top-level view added to the
 * window manager. It provides standard UI policies such as a background, title
 * area, default key processing, etc.
 *
 * <p>The only existing implementation of this abstract class is
 * android.view.PhoneWindow, which you should instantiate when needing a
 * Window.
 */
public abstract class Window {

所以可以判断只有PhoneWindow实现了Window
搜索一下setWindowManager,只有Activity的attach函数中调用

public class PhoneWindow extends Window implements MenuBuilder.Callback {
    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) {
        mWindow = new PhoneWindow(this, window);
        mWindow.setWindowControllerCallback(this);
        mWindow.setCallback(this);
        mWindow.setOnWindowDismissedCallback(this);
            mWindow.getLayoutInflater().setPrivateFactory(this);
        mWindow.setWindowManager(
                (WindowManager)context.getSystemService(Context.WINDOW_SERVICE),
                mToken, mComponent.flattenToString(),
                (info.flags & ActivityInfo.FLAG_HARDWARE_ACCELERATED) != 0);

每个PhoneWindow或者Window会创建一个WindowManagerImpl用来addView

activity的attach是在ActivityThread的performLaunchActivity中调用的,代码如下:


    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);
...
}

这个过程是就是activity启动的过程了,所以不再展开

发布了66 篇原创文章 · 获赞 18 · 访问量 18万+
展开阅读全文

没有更多推荐了,返回首页

©️2019 CSDN 皮肤主题: 大白 设计师: CSDN官方博客

分享到微信朋友圈

×

扫一扫,手机浏览