赞
踩
WMS(WindowManagerService) 是Framework一个重要的概念.
先从Window/WindowManager 理解入手,后续在进一步了解WMS.
Activity/Dialog /Toast 的视图(View) 都是附加到Window上 。
可以这么说, Android 上的一切视图即我们看到的, 都是通过 Window 呈现出来的.
它是 顶级窗口外观 和 行为策略 的抽象基类。
实现类为PhoneWindow(有且仅有这个实现类)。
从源码上看,
(1) 它定义了 Window 状态变化的回调接口 (按键事件/ focus / attached).
(2) 保存一个 mWindowManager 对象,因为View的管理最终依赖WindowManager实现.
外接通过创建 PhoneWindow 实例,然后获取 WindowManager实例对象,
最后调用 Window.setWindowManager 设置给Window本身 (如果传递wm为空也会重现获取一个.)
package android.view; public abstract class Window { public interface Callback { public boolean dispatchKeyEvent(KeyEvent event); public boolean dispatchTouchEvent(MotionEvent event); public void onWindowAttributesChanged(WindowManager.LayoutParams attrs); public void onContentChanged(); public void onWindowFocusChanged(boolean hasFocus); public void onAttachedToWindow(); public void onDetachedFromWindow(); } public interface OnWindowDismissedCallback { void onWindowDismissed(boolean finishTask, boolean suppressWindowTransition); } /** @hide */ public interface WindowControllerCallback { void updateStatusBarColor(int color); void updateNavigationBarColor(int color); } public void setWindowManager(WindowManager wm, IBinder appToken, String appName, boolean hardwareAccelerated) { mAppToken = appToken; mAppName = appName; ... if (wm == null) { wm = (WindowManager)mContext.getSystemService(Context.WINDOW_SERVICE); } mWindowManager = ((WindowManagerImpl)wm).createLocalWindowManager(this); } public void setFlags(int flags, int mask) { ... } }
(3) 定义设置、获取视图 : DecorView(顶级) / 状态栏颜色 / 导航栏背景
public abstract void setContentView(@LayoutRes int layoutResID);
public abstract @NonNull View getDecorView();
public abstract void setNavigationBarColor(@ColorInt int color);
public abstract void setStatusBarColor(@ColorInt int color);
public abstract int getStatusBarColor();
public abstract int getNavigationBarColor();
所以,Window 是View的直接管理者。
package com.android.internal.policy; public class PhoneWindow extends Window implements MenuBuilder.Callback { private DecorView mDecor; public PhoneWindow(@UiContext Context context, Window preservedWindow, ActivityConfigCallback activityConfigCallback) { if (preservedWindow != null) { mDecor = (DecorView) preservedWindow.getDecorView(); } } private void installDecor() { mForceDecorInstall = false; if (mDecor == null) { mDecor = generateDecor(-1); .............. } }
例如,Activity收到点击时间后,通过Window将事件传递给DecorView,再分发给我们自己的view(事件分发机制)
每个Window 对应一个View 和ViewRootImpl.
ViewRootImpl 作为 Window 和 View的桥梁。
(实际上Window是不存在的,以View的形式表示,即View是实体)
ViewManager接口定义了 添加、更新、删除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
{
public void addView(View view, ViewGroup.LayoutParams params);
public void updateViewLayout(View view, ViewGroup.LayoutParams params);
public void removeView(View view);
}
WindowManager 接口 继承 ViewManager.
@SystemService(Context.WINDOW_SERVICE)
public interface WindowManager extends ViewManager {
因此,它实际上是操作Window 中的View.
它的操作是通过它的实现类 WindowManagerImpl/WindowManagerGlobal(最终实现)
有几个重要的成员变量:
@UnsupportedAppUsage
private final ArrayList<View> mViews = new ArrayList<View>();
@UnsupportedAppUsage
private final ArrayList<ViewRootImpl> mRoots = new ArrayList<ViewRootImpl>();
@UnsupportedAppUsage
private final ArrayList<WindowManager.LayoutParams> mParams =
new ArrayList<WindowManager.LayoutParams>();
其中,
mView 表示每个已添加的View
mRoot 表示每一个ViewRootImpl
mParams 表每一个 布局参数
因此,在addView 添加View 的时候,会把当前view对应的三个参数保存起来
public void addView(View view, ViewGroup.LayoutParams params,
Display display, Window parentWindow, int userId) {
final WindowManager.LayoutParams wparams = (WindowManager.LayoutParams) params;
root = new ViewRootImpl(view.getContext(), display);
view.setLayoutParams(wparams);
mViews.add(view);
mRoots.add(root);
mParams.add(wparams);
至于最后的完成添加Window的过程,是通过ViewRootImpl.setView,
然后再通过 IWindowSession (Binder) IPC 通信,由WindowManagerService(System_server进程)完成.(因此, ViewRootImpl 负责和 WMS交互 )
(app 进程(android.view) -> system_server进程)
链接:https://juejin.cn/post/7076274407416528909#heading-25
作者:行走中的3卡
如果你想要深入系统的学习Android Framework框架,这里可以分享一份《Android Framework源码开发揭秘》,其中记录了从系统启动流程到WMS全部源码解析,相信你能优秀地学习整个Framework框架。
因文章篇幅原因,只放了部分内容,完整版扫码免费领取~
各位小伙伴们如果有需要这份《Android Framework源码开发揭秘》资料,点击下方卡片即可【免费领取】
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。