一场Toast引发的血案---WindowManager

2023-10-11 21:48

本文主要是介绍一场Toast引发的血案---WindowManager,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

在一场Toast引发的血案—Toast的显示中,已经大致了解了Toast的显示过程,但是还是有很多疑惑,Toast最终现实的时候是要通过WindowManager添加到一个Window的,但是这个WindowManager是哪个WindowManager,带着这个疑惑,我们开始深入。

可能在此之前对Window不是很了解,但这不影响对WindowManager的理解,只需要大概知道一个Activity,一个Dialog在显示的时候对应这一个Window即可。

WindowManger对象的产生

要使用WindowManger必须要获取WindowManger,获取WindowManger是通过context.getSystemService(Context.WINDOW_SERVICE),但是WindowManager对象究竟是怎么产生的呢?在ContextImpl中看到了下面的代码:

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

再跟踪到SystemServiceRegistry中发现了下面的代码:

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

感觉这和我的理解不太一样,WindowManager不应该是一个单例吗?再到WindowManagerImpl中看下。突然发现了下面的代码:

private final WindowManagerGlobal mGlobal = WindowManagerGlobal.getInstance();

在我们经常使用的addView函数中也有mGlobal:

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

removeView函数就直接使用了mGlobal.removeView

public void removeView(View view) {mGlobal.removeView(view, false);
}@Override
public void removeViewImmediate(View view) {mGlobal.removeView(view, true);
}

到这里,我们已经知道每个WindowManager的实例都不一样,但是每部都是在使用WindowManagerGlobal的单利对象对Window上的控件进行管理。为了不影响对Toast的分析,WindowManagerGlobal我会在后面单独分析。

WindowManager的获取

上面分析了WindowManger对象的产生,接下来就要分析下WindowManager对象的获取。在没有看相关源码之前,我一直以为context.getSystemService(Context.WINDOW_SERVICE)在那都是一样的,可以不用特别关注context的区别,直到我在Activity中看到了下面的代码:

public Object getSystemService(@ServiceName @NonNull String name) {......if (WINDOW_SERVICE.equals(name)) {return mWindowManager;} else if (SEARCH_SERVICE.equals(name)) {ensureSearchManager();return mSearchManager;}return super.getSystemService(name);
}

wc,Activity还针对getSystemService进行了特殊处理,如果是为了获取WindowManager或者SearchManager,就会去拿Activity的属性mWindowManager。看下mWindowManager是如何产生的

代码段1
mWindow = new PhoneWindow(this, window, activityConfigCallback);
代码段2
mWindow.setWindowManager((WindowManager)context.getSystemService(Context.WINDOW_SERVICE),mToken, mComponent.flattenToString(),(info.flags & ActivityInfo.FLAG_HARDWARE_ACCELERATED) != 0);
代码段3
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);
}

发现最终mWindowManager是由WindowManagerImplcreateLocalWindowManager方法产生的,而createLocalWindowManager最终会调用

return new WindowManagerImpl(mContext, parentWindow);

突然感觉有回到了上一部分。

有了Activity的教训,我赶紧去看了ServiceApplicaiton,最终确认没有都是直接调用了ContextImplgetSystemService方法,并没有对服务进行特殊的处理。

总结

上面分析了WindowManager的产生和获取,可以发先每个context都可以获取自己的WindowManager实例,以便对Window进行操作,但是WindowManager实例实际上是通过WindowManagerGlobal的单利对象对Window进行操作的。

这篇关于一场Toast引发的血案---WindowManager的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/191041

相关文章

Caused by: android.view.WindowManager$BadTokenException: Unable to add window -- token android.os.B

一个bug日志 FATAL EXCEPTION: main03-25 14:24:07.724: E/AndroidRuntime(4135): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.syyx.jingubang.ky/com.anguotech.android.activity.Init

Vite + Vue3 +Vant4出现Toast is not a function

今天写前端的时候出现了这个问题搞了我一会 搜集原因: 1:是vant版本的问题,Toast()的方法是vant3版本的写法,而我用的是vant4,vant4中的写法改成了showToast()方法,改正过来 import {showToast} from "vant";  发现还是报错,说是找不到对应的样式文件 2:Vant 从 4.0 版本开始不再支持 babel-plugin-i

一道算法题引发的动态内存管理的思考

在做PKU2762时,需要建邻接表。 于是按部就班写了下面一个插入边到邻接表中的函数: const int VMAX = 1010;typedef struct Graph{int vex;Graph* next;}Graph;Graph ArcGraph[VMAX];void insert(int u, int v){Graph* t = new Graph;Graph*

HTML5将会带来一场Web革命

一个不起眼的对网页的标记机制为何有这么大的影响? HTML5 引起的广泛关注是否仅仅是一时的科技狂热? 总之,为什么计算机专家需要关心这个呢?   AD:2013云计算架构师峰会课程资料下载   面向万维网(WWW)的软件开发人员认为新的 HTML5 规范正在革新现有 Web 系统的呈现、工作、使用方式。他们说 HTML5 简化了程序员的工作,使访问多种多样的设备和应用程序更加方便,并且提

一生中错过多少次,就像昨夜下了一场雨,而我却在睡梦中

许多的事情,总是在经历过以后才会懂得。一如感情,痛过了,才会懂得如何保护自己;傻过了,才会懂得适时地坚持与放弃,在得到与失去中我们慢慢地认识自己。既然默默相守已失去意义,莫不如立即斩断心中那情思屡屡,放弃你所珍爱的,期待的,重新选择。其实,生活并不需要这么些无谓的执着,没有什么就真的不能割舍。学会放弃,生活会更容易。

引发蛀牙、避免蛀牙食物大全

引发蛀牙、避免蛀牙食物大全 引发蛀牙的食物大全: 糖果 糖浆 糖果棒 巧克力 碳酸饮料 果汁 口香糖 蜂蜜 蛋糕 甜点 薯片 脆饼干 果酱 果冻 蜜饯 蜜饯果干 避免蛀牙的食物大全: 高纤维蔬菜 水果 坚果 种子 高钙乳制品 高蛋白质肉类 高蛋白质鱼类 绿茶 水 蔬菜汤 鸡汤 酸奶 酸奶制品 奶酪 红薯 土豆 面包和全麦面包 芝士

捉虫笔记(四)-- 空格引发的悬案

空格引发的悬案 1、描述现象: 在代码中有一段利用rmdir指令删除目录代码,但是有用户反馈一直删除失败,但是有没有看到错误的日志信息,正好有同事能复现,所以今天好好探究一番。 2、思考过程 很好奇的一点就是为什么有的环境就是正常。 首先想到2个问题: ①代码有没有执行。 ②假如执行,有没有错误。 关于这两个问题都有个难点,我该如何下断点: 2.1、分析代码是否执行 删除目录的

“苹果税”引发的苹果与腾讯、字节跳动之间的纷争与博弈

北京时间9月10日凌晨一点的Apple特别活动日渐临近,苹果这次将会带来iPhone16系列新品手机及其他硬件产品的更新,包括iPad、Apple Watch、AirPods等。从特别活动的宣传图和宣传标语“閃亮時刻”来看,Apple Intelligence将会是史上首次推出,无疑将会是iOS 18的重头戏和高光时刻。 不过就在9月2日,一则“微信可能不支持iPhone16”的

锁屏界面无法无法显示Toast

在锁屏界面开发几个快捷方式启动某些应用,例如:Calculator, Camera,Google voice和Call等,界面如下。且这种做法很普遍,很多厂商都有。 说明: 1>左边图片右下角为快速启动Calculator的快捷方式,在无需解锁的情况下,进入Calcaulator应用。 2>右边图片为从launcher中启动Calculator后,操作时弹出的Toast提示。 那么问

后台应用服务弹自定义Toast框

之前看到自己的手机应用突然会弹出一个提示框感到有点神奇,不知道是怎么做到的,后面才了解到是后台服务弹的。后台服务弹Toast框其实跟Activity界面差不多,下面先来看看项目SimpleJarService结构: ├── AndroidManifest.xml ├── Android.mk ├── libs │  ├── android-support-v4.jar │  ├── f