相关类:

  • Window:是一个抽象类,只是一个概念并不实际存在,唯一实现类是PhoneWindow,其对View进行管理
  • WindowManager:一个接口类,继承自ViewManager,字面意思对Window进行管理,实际上是对View进行添加,删除及更新操作.实现类是WindowManagerImpl
/*** code 1*/
public interface ViewManager
{public void addView(View view, ViewGroup.LayoutParams params);public void updateViewLayout(View view, ViewGroup.LayoutParams params);public void removeView(View view);
}
  • WindowManagerService(WMS):实际对View进行处理的类,通过IPC与WindowManager进行通信

Activity通过ActivityThread中的performLaunchActivity()方法完成整个启动流程,并通过ClassLoader类加载器创建Activity的实例,并调用attach方法关联其运行过程所依赖的一系列上下文环境变量:
frameworks/base/core/java/android/app/ActivityThread.java

/*** code 2*/
private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {ContextImpl appContext = createBaseContextForActivity(r);Activity activity = null;java.lang.ClassLoader cl = appContext.getClassLoader();activity = mInstrumentation.newActivity(cl, component.getClassName(), r.intent);if (activity != null) {Window window = null;//如果保存Activity信息的ActivityClientRecord实例中mPendingRemoveWindow不为空,则使用使用已保存的window对象if (r.mPendingRemoveWindow != null && r.mPreserveWindow) {window = r.mPendingRemoveWindow;r.mPendingRemoveWindow = null;r.mPendingRemoveWindowManager = null;}appContext.setOuterContext(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);}
}
  • ActivityClientRecord中的mPendingRemoveWindow只在handleDestroyActivity方法中出现过赋值代码,而用于判断的mPreserveWindow(是否保留window)则出现在handleRelaunchActivity方法中,relaunch也就是先销毁再启动,将mPreserveWindow改为true,再调用handleDestroyActivity把延迟销毁的window和wms对象进行保存,然后将Activity销毁,最后调用handleLaunchActivity,走performLaunchActivity方法重新拉起Activity,这时就走到了上面这段代码,attach方法中的window对象就由刚才销毁Activity后保存的window对象赋值.
/***  code 3*  此处ActivityThread会回调Activitiy的onDestroy方法*/
private void handleDestroyActivity(IBinder token, boolean finishing,int configChanges, boolean getNonConfigInstance) {...if (r.activity.mWindowAdded) {if (r.mPreserveWindow) {// 延迟移除window和wms对象,直到新Activity中的window被添加r.mPendingRemoveWindow = r.window;r.mPendingRemoveWindowManager = wm;// We can only keep the part of the view hierarchy that we control,// everything else must be removed, because it might not be able to// behave properly when activity is relaunching.r.window.clearContentView();} else {wm.removeViewImmediate(v);}...}
  • 那么如果是正常的启动Activity呢?attach方法中传参window将为空,现在走进attach方法,可以看到Window的具体实现类就是PhoneWindow,PhoneWindow直接在attach方法中创建实例,并设置回调接口,在Callback接口中有诸如dispatchTouchEvent,onAttachToWindow等方法
/*** code 4*/
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) {attachBaseContext(context);mFragments.attachHost(null /*parent*/);mWindow = new PhoneWindow(this, window, activityConfigCallback);mWindow.setWindowControllerCallback(this);mWindow.setCallback(this);mWindow.setOnWindowDismissedCallback(this);...mWindow.setWindowManager((WindowManager)context.getSystemService(Context.WINDOW_SERVICE),mToken, mComponent.flattenToString(),(info.flags & ActivityInfo.FLAG_HARDWARE_ACCELERATED) != 0);...

在attach方法中直接实例化了PhoneWindow,并在下面的setWindowManager方法为Window设置WindowManager,此方法在PhoneWindow父类Window中:
frameworks/base/core/java/android/view/Window.java

 /*** code 5*/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);}

如果传入的WindowManager为空,则通过mContext.getSystemService(Context.WINDOW_SERVICE)来获取,此处Context实现类是ContextImpl,为什么呢?这里要先找到Activity实例化的地方,也就是ActivityThread的performLaunchActivity方法,即文章的第一段代码code1,其中第一行代码:

ContextImpl appContext = createBaseContextForActivity(r);
/*** code 6*/
private ContextImpl createBaseContextForActivity(ActivityClientRecord r) {final int displayId;try {displayId = ActivityManager.getService().getActivityDisplayId(r.token);} catch (RemoteException e) {throw e.rethrowFromSystemServer();}//annotation 1ContextImpl appContext = ContextImpl.createActivityContext(this, r.packageInfo, r.activityInfo, r.token, displayId, r.overrideConfig);final DisplayManagerGlobal dm = DisplayManagerGlobal.getInstance();// For debugging purposes, if the activity's package name contains the value of// the "debug.use-second-display" system property as a substring, then show// its content on a secondary display if there is one.String pkgName = SystemProperties.get("debug.second-display.pkg");if (pkgName != null && !pkgName.isEmpty()&& r.packageInfo.mPackageName.contains(pkgName)) {for (int id : dm.getDisplayIds()) {if (id != Display.DEFAULT_DISPLAY) {Display display =dm.getCompatibleDisplay(id, appContext.getResources());appContext = (ContextImpl) appContext.createDisplayContext(display);break;}}}return appContext;}

这里appContext是ClassLoader获取的来源,而Activity又是通过类加载器生成,也就是说Activity中的context来源于ContextImpl的
createActivityContext方法,即注释1,看到这里也就明白了getSystemService的来源,让我们继续顺着ContextImpl往下看
frameworks/base/core/java/android/app/ContextImpl.java

/*** code 7*/
@Override
public Object getSystemService(String name) {return SystemServiceRegistry.getSystemService(this, name);}

这里会调用SystemServiceRegistry.getSystemService(this, name),点进这个类会发现这个类是管理所有可以被返回也就是可以被调用的系统服务
frameworks/base/core/java/android/app/SystemServiceRegistry.java

private static final HashMap<String, ServiceFetcher<?>> SYSTEM_SERVICE_FETCHERS =new HashMap<String, ServiceFetcher<?>>();
/*** code 8*/
public static Object getSystemService(ContextImpl ctx, String name) {ServiceFetcher<?> fetcher = SYSTEM_SERVICE_FETCHERS.get(name);return fetcher != null ? fetcher.getService(ctx) : null;}

查看代码发现,getSystemService传入的name相当于key,还记得传入的是什么吗?
Context.WINDOW_SERVICE

public static final String WINDOW_SERVICE = "window";

也就是说当我们传入对应的上下文及key时会返回给我们fetcher.getService方法返回的对象,那"window"返回的是什么呢?已知systemservice来源于名为SYSTEM_SERVICE_FETCHERS的HashMap,那么全局查找该map的put方法,定位如下:

/*** code 9*/
private static <T> void registerService(String serviceName, Class<T> serviceClass,ServiceFetcher<T> serviceFetcher) {SYSTEM_SERVICE_NAMES.put(serviceClass, serviceName);SYSTEM_SERVICE_FETCHERS.put(serviceName, serviceFetcher);}

查找registerService方法的调用发现,SystemServiceRegistry存在一个静态代码块,里面通过registerService方法注册了所有的系统服务,而我们要找的WINDOW_SERVICE就在其中:

/*** code 10*/
static {registerService(Context.WINDOW_SERVICE, WindowManager.class,new CachedServiceFetcher<WindowManager>() {@Overridepublic WindowManager createService(ContextImpl ctx) {return new WindowManagerImpl(ctx);}});
}

CachedServiceFetcher是一个抽象类,真正返回的是WindowManagerImpl,也就是说getSystemService(Context.WINDOW_SERVICE)最终返回的是WindowManagerImpl对象,这样我们结束ContextImpl及SystemServiceRegistry源码的查看,重新返回到Window抽象类的setWindowManager方法中,也就是code 5,在获得WindowManagerImpl对象后继续向下走,会发现调用了createLocalWindowManager方法,点进去看看

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

/*** code 11*/
public WindowManagerImpl createLocalWindowManager(Window parentWindow) {return new WindowManagerImpl(mContext, parentWindow);
}private WindowManagerImpl(Context context, Window parentWindow) {mContext = context;mParentWindow = parentWindow;
}

这里还是实例化了一个WindowManagerImpl,和前面的区别在于SystemServiceRegistry静态代码块中实例化的WindowManagerImpl构造函数只有上下文,而这次构造方法中传入了Window,也就是说WindowManagerImpl持有了Window的引用,这样的话就可以在window中进行增加删除view的操作了,接下来看addView方法:

/*** code 12*/
private final WindowManagerGlobal mGlobal = WindowManagerGlobal.getInstance();@Override
public void addView(@NonNull View view, @NonNull ViewGroup.LayoutParams params) {applyDefaultToken(params);mGlobal.addView(view, params, mContext.getDisplay(), mParentWindow);
}
  • 本以为WindowManagerImpl就是终点,没想到真正对View操作的并不是它,而是WindowManagerGlobal,这里通过单例模式获取其实例,并对view进行实际操作

到目前为止,我们可以大概梳理一下Window与WindowManager之间的关系:

  1. PhoneWindow继承于Window抽象类,本质上也是View.其内部通过setWindowManager方法与WindowManager产生关联(实例化WindowManagerImpl)
  2. ViewManager接口内部有对view进行添加删除更新的方法,WindowManager继承ViewManager,WindowManagerImpl又继承WindowManager
  3. Window与WindowManager产生关联,最后也就是两者的实现类PhoneWindow与WindowManagerImpl绑定
  4. 在WindowManagerImpl内部实际处理view的其实是WindowManagerGlobal(桥接模式)

参考:

  1. http://liuwangshu.cn/framework/wm/1-windowmanager.html
  2. https://blog.csdn.net/weixin_41101173/article/details/79685305
  3. https://blog.csdn.net/tonyandroid1984/article/details/71046368
  4. Android开发艺术探索

Window与WindowManager相关推荐

  1. Android开发艺术探索》读书笔记 (8) 第8章 理解Window和WindowManager

    第8章 理解Window和WindowManager 8.1 Window和WindowManager (1)Window是抽象类,具体实现是PhoneWindow,通过WindowManager就可 ...

  2. Android之Window与WindowManager

     Window表示一个窗口的概念,在日常开发中直接接触Window的机会并不多,但却会经常用到Window,activity.toast.dialog.PopupWindow.状态栏等都是Window ...

  3. Android GUI之Window、WindowManager

    通过前几篇的文章(查看系列文章:http://www.cnblogs.com/jerehedu/p/4607599.html#gui ),我们清楚了Activity实际上是将视图的创建和显示交给了Wi ...

  4. Activity Window View WindowManager关系Touch事件分发机制

    http://www.cnblogs.com/linjzong/p/4191891.html https://www.cnblogs.com/kest/p/5141817.html https://b ...

  5. Android中的Window、WindowManager以及悬浮框视频播放的实现

    摘要:近日看公司直播项目,其中有一个功能就是退出某房间之后,直播界面会以悬浮窗的形式出现,并且可以拖动悬浮窗到界面中任意位置,点击悬浮框之后,又可以回到房间中继续观看直播.现在这个功能在主流的直播或者 ...

  6. Android源码分析之理解Window和WindowManager

    Window和WindowManager概述 Window是一个抽象类,它的具体实现是PhoneWindow,创建一个Window通过WindowManager 就可以完成.WindowManager ...

  7. [转]Android 之 Window、WindowManager 与窗口管理

    这篇是对前两天研究的悬浮窗的内容的一个小小的资料整理吧.首先是转载一篇介绍Android窗口的内容,觉得写得不错:http://blog.csdn.net/xieqibao/article/detai ...

  8. Android 之 Window、WindowManager 与窗口管理

    其实在android中真正展示给用户的是window和view,activity在android中所其的作用主要是处理一些逻辑问题,比如生命周期的管理.建立窗口等.在android中,窗口的管理还是比 ...

  9. Android 带你彻底理解 Window 和 WindowManager

    有时候我们需要在桌面上显示一个类似悬浮窗的东西,这种效果就需要用 Window 来实现,Window 是一个抽象类,表示一个窗口,它的具体实现类是 PhoneWindow,实现位于 WindowMan ...

最新文章

  1. 2018年全球AI突破性技术TOP10
  2. DataTable的Compute方法和Expression语法
  3. 微信小程序一些知识点
  4. C#动态操作DataTable(新增行、列、查询行、列等)
  5. web前端教程:css实现容器高度适应屏幕高度
  6. cuid卡写入后锁死_CUID卡,CUID白卡,CUID门禁卡,CUID电梯卡,CUID可改写卡
  7. azure 入门_Azure数据目录入门
  8. 【JavaScript】JavaScript高级教程
  9. CHIP-seq 分析笔记
  10. 名师出高徒,我相信努力的我,会是高徒中的一员。
  11. Python转义字符及用法
  12. Oracle官网下载JDK8需要注册怎么办
  13. 关于react-router-dom 6.0.1的基础写法 解决Error: A <Route> is only ever to be used as the child of <Routes>
  14. 安装compiz-fusion
  15. 淘宝直播怎么做,主播怎么做才能引流,卖出产品
  16. Unexpected Exception caught setting 异常解决记录
  17. 智慧灯杆迈向标准化,5G智能灯杆网关加速“数字覆城”
  18. 当时若爱韩公子,埋骨成灰恨未休
  19. 目标检测_0.1检测目标和真值(ground truth)匹配
  20. hough函数 matlab,matlab中hough函数

热门文章

  1. Sorry, this application cannot run under a Virtual Machine的解决
  2. echarts data 赋值
  3. 2022-2027年中国B2C电子商务行业市场深度分析及投资战略规划报告
  4. 三款免费的AI绘画网站对比分析,真正好用的居然是它
  5. Qt编写项目作品26-一维码二维码解析及生成
  6. hashmap的特性?HashMap底层源码,数据结构?Hashmap和hashtable ConcurrentHashMap区别?
  7. 绝了!深圳java工资一般多少
  8. 留学计算机专业排名,2016年美国留学计算机专业大学排名
  9. 干货分享 | 网络安全等级保护网络设备、安全设备知识点汇总
  10. greenplum-db-5.10 for Centos 7.6 分布式安装,使用,备份与恢复