-
token在创建ActivityRecord的时候一起被创建,他是一个IBinder对象,实现了接口IApplicationToken。
-
token创建后会发送到WMS,在WMS中封装成WindowToken,并存在一个HashMap<IBinder,WindowToken>。
-
token会随着ActivityRecord被发送到本地进程,ActivityThread根据AMS的指令执行Activity启动逻辑。
-
Activity启动的过程中会创建PhoneWindow和对应的WindowManager,同时把token存在PhoneWindow中。
-
通过Activity的WindowManager添加view/弹出dialog时会把PhoneWindow中的token放在窗口LayoutParams中。
-
通过viewRootImpl向WMS进行验证,WMS在LayoutParams拿到IBinder之后就可以在Map中获取WindowToken。
-
根据获取的结果就可以判断该token的合法情况。
-
token看着是属于window机制的领域内容,其实是context的知识范畴。我们知道context一共有三种最终实现类:Activity、Application、Service,context是区分一个类是普通Java类还是android组件的关键。context拥有访问系统资源的权限,是各种组件访问系统的接口对象。但是,三种context,只有Activity允许有界面,而其他的两种是不能有界面的,也没必要有界面。为了防止开发者乱用context造成混乱,那么必须对context的权限进行限制,这也就是token存在的意义。拥有token的context可以创建界面、进行UI操作,而没有token的context如service、Application,是不允许添加view到屏幕上的(这里的view除了系统窗口)。
-
为什么说这不属于window机制的知识范畴?从window机制中我们知道WMS控制每一个window,是通过viewRootImpl中的IWindowSession来进行通信的,token在这个过程中只充当了一个验证作用,且当PhoneWindow显示了DecorView之后,后续添加的View使用的token都是ViewRootImpl的IWindowSession对象。这表示当一个PhoneWindow可以显示界面后,那么对于后续其添加的view无需再次进行权限判断。因而,token真正限制的,是context是否可以显示界面,而不是针对window。
-
而我们了解完底层逻辑后,不是要去知道怎么绕过他的限制,动一些“大胆的想法”,而是要知道官方这么设计的目的。我们在开发的时候,也要针对不同职责的context来执行对应的事务,不要使用Application或Service来做UI操作。
Android之Token
最新推荐文章于 2021-09-18 20:35:59 发布