android 窗口管理服务实现机制
来源:互联网 发布:java中wait的用法 编辑:程序博客网 时间:2024/05/16 10:35
窗口管理是ANDROID框架一个重要部分,主要包括如下功能:
(1)Z-ordered的维护
(2)窗口的创建、销毁
(3)窗口的绘制、布局
(4)Token管理,AppToken
(5)活动窗口管理(FocusWindow)
(6)活动应用管理(FocusAPP)
(7)输入法管理
(8)系统消息收集与分发
这些功能主要有一个窗口管理服务和相应的客户端来实现,实现机制是标准的ANDROID系统服务实现机制--基于代理模式和CORBA模式的实现机制:客户端通过远程代理使用BINDER驱动与服务进行交互.
窗口管理的整个类图如下:
整个类图包括客户端和服务端两大部分,服务端的类主要有WindowManagerService、WindowState、Session、SurfaceSession、Surface等主要类。WindowManagerService、Session派生自各自的本地桩(STUB)。而这些桩和连同远程访问代理都是通过AIDL 文件自动生成的,STUB提供了服务管理接口的本地IPC桩实现,且派生自Binder类,远程访问代理Proxy提供了服务管理接口的远端实现,代理根据本地服务的引用访问本地服务,实现远端访问本地服务的目的。因此借助STUB 提供IPC本地服务访问接口,Proxy提供远端访问接口,可以实现客户端访问服务的目标。
如下是根据AIDL文件自动生成的IWindowManager.java和IWindowSession.java代码片断。
客户端都通过如下接口获得窗口管理服务远端代理对象,该接口首先通过ServiceManager(0号服务)的getService接口使用窗口管理服务在ServiceManager中登记时使用的服务名字获得窗口管理服务的引用,并传进IWindowManager.Stub.asInterface 获得一个窗口管理服务远端代理对象,然后使用该远端代理对象访问窗口管理服务。
Session对象也是服务端提供的供客户端可以访问的对象,服务端使用Session对象指示一个客户端与窗口管理服务交互实现窗口操作的会话,通常为每个与窗口管理交互的进程打开一个Session对象,在服务端维护一个Session对象列表管理每一个Session,在Session会话期间,客户端可以通过该Session对象与窗口管理服务实现窗口交互,如窗口的创建、销毁、绘制、布局等,保证一个Session期间窗口状态的一致。
Session对象在一个进程新建第一个窗口时使用窗口管理接口的openSession接口创建,第一个窗口新建期间也创建一个SurfaceSession对象用来实现窗口和视图绘制操作。SurfaceSession对象用来与SurfaceFliger 服务建立连接,实现窗口和视图在显示硬件上的实际输出工作。
服务端的Surface类是一个处理窗口输出的对象,窗口和视图使用Surface类进行实际的绘制.
服务端为每个窗口创建一个Surface对象,并在该对象中通过JNI创建一个C++层负责绘制的SurfaceControl对象,并把该Surface对象创建的SurfaceControl对象的引用传给客户端的Surface对象中,因此客户端的Surface对象就可以使用和服务端Surface对象一样的SurfaceControl对象进行绘制控制了.
服务端使用WindowState对象代表每一个窗口,每一个窗口的WindowState对象依据窗口的Z-ordered 放在mWindows数组中,也根据客户端窗口对应的W类对象放到mWindowMap中。
每个窗口都对应一个WindowToken标记和AppWindowToken标记,服务端使用WindowToken唯一标识每一个窗口,并在addWindow函数中根据标示客户端窗口的attrs.token为键值保存到窗口服务的HashMap 变量中mTokenMap.
attrs.token 是窗口布局参数中LayoutParams的一个binder 对象,在客户端LocalWindowManager新建窗口addView时赋值,主窗口类型对应ACTIVITY的AppToken,子窗口类型对应主视图的WindowToken。
使用AppWindowToken对象标识与窗口绑定的ACTIVITY, 在ACTIVITY启动时赋值,并也依据对应窗口的Z-ordered放在mAppTokens数组中.
客户端负责窗口操作的主要有四个类 :
ViewRootImpl 视图处理类,继承自Handler,实现客户端窗口及VIEW与窗口管理服务的交互和事件处理,因此ViewRootImpl是一个中介模式的采用。内部也有一个W类对象mWindow,派生自IWindow.Stub,是代表客户端窗口的一个桩对象,窗口管理服务通过该对象与客户端交互。客户端与窗口服务打开的会话保存在sWindowSession变量中,因此客户端使用sWindowSession与窗口管理服务发送请求,窗口管理服务使用mWindow向客户端回送应答,借助ViewRootImpl的两个BINDER对象实现客户端与窗口服务服务的双向交互。
WindowManagerImpl是客户端WindowManager管理接口的实现,用来通过ViewRootImpl发送窗口的创建、销毁和布局请求等。
VIEW类是视图的基类,视图的主 View通过AttachInfo对象借助ViewRootImpl绑定到窗口,ViewRootImpl也作为主视图的ViewParent。AttachInfo是视图的内部类
下面是一个打开一个窗口的序列图:
1 )客户端在创建窗口时调用getWindowManager获得本地窗口管理对象,并调用其addView函数,在这里为窗口的布局参数赋值,如窗口标题、包名字、token值、flag值等;
2)接着调用本地窗口管理对象的超类CompatModeWrapper的addView函数;
3)CompatModeWrapper是WindowManagerImpl的包装类,采用了桥接模式,达到实现和抽象的分离目的. 因此CompatModeWrapper函数addView转而调用WindowManagerImpl的addView函数;
4)WindowManagerImpl的addView函数首先查看要add的视图是否已经存在,若不存在时实例化一个ViewRootImpl对象,并把view和ViewRootImpl对象及布局参数保存到本地数组中,接着调用ViewRootImpl对象的setView函数;
5)ViewRootImpl对象的setView函数首先请求进行窗口的第一次布局(调用requestLayout),然后根据窗口属性是否支持输入实例化一个InputChannel,然后通过服务端远程代理对象sWindowSession向服务端发出新建窗口的请求(调用其add接口);最后还要registerInputChannel和把视图assignParent;
6)服务端的Session对象收到addwindow的请求,就调用窗口管理服务的addWindow函数来完成新建窗口的任务,完成实际创建窗口的工作。首先实例化一个WindowState对象代表新建的窗口,接着使用客户端窗口的BINDER对象(W对象)为键值把WindowState对象放入mWindowMap中,并根据Z-ORDER放入WindowState的数组中,还要调用WindowState对象的attach函数与Session完成绑定,并在SurfaceSession没有创建时完成创建;然后新建或获得WindowToken,并使用传进来的客户端窗口布局参数中的token值把WindowToken放入mTokenMap中;最后根据窗口能否能够接收键值更新焦点窗口。转自固弘博客
(1)Z-ordered的维护
(2)窗口的创建、销毁
(3)窗口的绘制、布局
(4)Token管理,AppToken
(5)活动窗口管理(FocusWindow)
(6)活动应用管理(FocusAPP)
(7)输入法管理
(8)系统消息收集与分发
这些功能主要有一个窗口管理服务和相应的客户端来实现,实现机制是标准的ANDROID系统服务实现机制--基于代理模式和CORBA模式的实现机制:客户端通过远程代理使用BINDER驱动与服务进行交互.
窗口管理的整个类图如下:
整个类图包括客户端和服务端两大部分,服务端的类主要有WindowManagerService、WindowState、Session、SurfaceSession、Surface等主要类。WindowManagerService、Session派生自各自的本地桩(STUB)。而这些桩和连同远程访问代理都是通过AIDL 文件自动生成的,STUB提供了服务管理接口的本地IPC桩实现,且派生自Binder类,远程访问代理Proxy提供了服务管理接口的远端实现,代理根据本地服务的引用访问本地服务,实现远端访问本地服务的目的。因此借助STUB 提供IPC本地服务访问接口,Proxy提供远端访问接口,可以实现客户端访问服务的目标。
如下是根据AIDL文件自动生成的IWindowManager.java和IWindowSession.java代码片断。
[Java] 纯文本查看 复制代码
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
public
interface
IWindowManager
extends
android.os.IInterface
{
public
static
abstract
class
Stub
extends
android.os.Binder
implements
android.view.IWindowManager
{
private
static
final
java.lang.String DESCRIPTOR =
"android.view.IWindowManager"
;
public
Stub()
{
this
.attachInterface(
this
, DESCRIPTOR);
}
public
static
android.view.IWindowManager asInterface(android.os.IBinder obj)
{
if
((obj==
null
)) {
return
null
;
}
android.os.IInterface iin = (android.os.IInterface)obj.queryLocalInterface(DESCRIPTOR);
if
(((iin!=
null
)&&(iin
instanceof
android.view.IWindowManager))) {
return
((android.view.IWindowManager)iin);
}
return
new
android.view.IWindowManager.Stub.Proxy(obj);
}
public
android.os.IBinder asBinder()
{
return
this
;
}
@Override
public
boolean
onTransact(
int
code, android.os.Parcel data, android.os.Parcel reply,
int
flags)
throws
android.os.RemoteException
{
switch
(code)
{
}
}
Proxy(android.os.IBinder remote)
{
mRemote = remote;
}
public
android.os.IBinder asBinder()
{
return
mRemote;
}
public
boolean
startViewServer(
int
port)
throws
android.os.RemoteException
{
android.os.Parcel _data = android.os.Parcel.obtain();
android.os.Parcel _reply = android.os.Parcel.obtain();
_data.writeInterfaceToken(DESCRIPTOR);
_data.writeInt(port);
mRemote.transact(Stub.TRANSACTION_startViewServer, _data, _reply,
0
);
//通过服务的远端引用发出访问请求。
}
}
客户端都通过如下接口获得窗口管理服务远端代理对象,该接口首先通过ServiceManager(0号服务)的getService接口使用窗口管理服务在ServiceManager中登记时使用的服务名字获得窗口管理服务的引用,并传进IWindowManager.Stub.asInterface 获得一个窗口管理服务远端代理对象,然后使用该远端代理对象访问窗口管理服务。
[Java] 纯文本查看 复制代码
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
static
IWindowManager getWindowManager() {
synchronized
(sStaticInit) {
if
(sWindowManager ==
null
) {
sWindowManager = IWindowManager.Stub.asInterface(
ServiceManager.getService(
"window"
));
}
return
sWindowManager;
}
}
Session对象也是服务端提供的供客户端可以访问的对象,服务端使用Session对象指示一个客户端与窗口管理服务交互实现窗口操作的会话,通常为每个与窗口管理交互的进程打开一个Session对象,在服务端维护一个Session对象列表管理每一个Session,在Session会话期间,客户端可以通过该Session对象与窗口管理服务实现窗口交互,如窗口的创建、销毁、绘制、布局等,保证一个Session期间窗口状态的一致。
Session对象在一个进程新建第一个窗口时使用窗口管理接口的openSession接口创建,第一个窗口新建期间也创建一个SurfaceSession对象用来实现窗口和视图绘制操作。SurfaceSession对象用来与SurfaceFliger 服务建立连接,实现窗口和视图在显示硬件上的实际输出工作。
服务端的Surface类是一个处理窗口输出的对象,窗口和视图使用Surface类进行实际的绘制.
服务端为每个窗口创建一个Surface对象,并在该对象中通过JNI创建一个C++层负责绘制的SurfaceControl对象,并把该Surface对象创建的SurfaceControl对象的引用传给客户端的Surface对象中,因此客户端的Surface对象就可以使用和服务端Surface对象一样的SurfaceControl对象进行绘制控制了.
服务端使用WindowState对象代表每一个窗口,每一个窗口的WindowState对象依据窗口的Z-ordered 放在mWindows数组中,也根据客户端窗口对应的W类对象放到mWindowMap中。
[Java] 纯文本查看 复制代码
1
2
3
final
ArrayList<WindowState> mWindows;
mWindowMap.put(client.asBinder(), win);
每个窗口都对应一个WindowToken标记和AppWindowToken标记,服务端使用WindowToken唯一标识每一个窗口,并在addWindow函数中根据标示客户端窗口的attrs.token为键值保存到窗口服务的HashMap 变量中mTokenMap.
[Java] 纯文本查看 复制代码
1
mTokenMap.put(attrs.token, token);
attrs.token 是窗口布局参数中LayoutParams的一个binder 对象,在客户端LocalWindowManager新建窗口addView时赋值,主窗口类型对应ACTIVITY的AppToken,子窗口类型对应主视图的WindowToken。
[Java] 纯文本查看 复制代码
1
2
3
4
5
6
7
8
9
public
static
class
LayoutParams
extends
ViewGroup.LayoutParams
implements
Parcelable {
public
IBinder token =
null
;
}
使用AppWindowToken对象标识与窗口绑定的ACTIVITY, 在ACTIVITY启动时赋值,并也依据对应窗口的Z-ordered放在mAppTokens数组中.
[Java] 纯文本查看 复制代码
1
final
ArrayList<AppWindowToken> mAppTokens =
new
ArrayList<AppWindowToken>();
客户端负责窗口操作的主要有四个类 :
ViewRootImpl 视图处理类,继承自Handler,实现客户端窗口及VIEW与窗口管理服务的交互和事件处理,因此ViewRootImpl是一个中介模式的采用。内部也有一个W类对象mWindow,派生自IWindow.Stub,是代表客户端窗口的一个桩对象,窗口管理服务通过该对象与客户端交互。客户端与窗口服务打开的会话保存在sWindowSession变量中,因此客户端使用sWindowSession与窗口管理服务发送请求,窗口管理服务使用mWindow向客户端回送应答,借助ViewRootImpl的两个BINDER对象实现客户端与窗口服务服务的双向交互。
WindowManagerImpl是客户端WindowManager管理接口的实现,用来通过ViewRootImpl发送窗口的创建、销毁和布局请求等。
VIEW类是视图的基类,视图的主 View通过AttachInfo对象借助ViewRootImpl绑定到窗口,ViewRootImpl也作为主视图的ViewParent。AttachInfo是视图的内部类
下面是一个打开一个窗口的序列图:
1 )客户端在创建窗口时调用getWindowManager获得本地窗口管理对象,并调用其addView函数,在这里为窗口的布局参数赋值,如窗口标题、包名字、token值、flag值等;
2)接着调用本地窗口管理对象的超类CompatModeWrapper的addView函数;
3)CompatModeWrapper是WindowManagerImpl的包装类,采用了桥接模式,达到实现和抽象的分离目的. 因此CompatModeWrapper函数addView转而调用WindowManagerImpl的addView函数;
4)WindowManagerImpl的addView函数首先查看要add的视图是否已经存在,若不存在时实例化一个ViewRootImpl对象,并把view和ViewRootImpl对象及布局参数保存到本地数组中,接着调用ViewRootImpl对象的setView函数;
5)ViewRootImpl对象的setView函数首先请求进行窗口的第一次布局(调用requestLayout),然后根据窗口属性是否支持输入实例化一个InputChannel,然后通过服务端远程代理对象sWindowSession向服务端发出新建窗口的请求(调用其add接口);最后还要registerInputChannel和把视图assignParent;
6)服务端的Session对象收到addwindow的请求,就调用窗口管理服务的addWindow函数来完成新建窗口的任务,完成实际创建窗口的工作。首先实例化一个WindowState对象代表新建的窗口,接着使用客户端窗口的BINDER对象(W对象)为键值把WindowState对象放入mWindowMap中,并根据Z-ORDER放入WindowState的数组中,还要调用WindowState对象的attach函数与Session完成绑定,并在SurfaceSession没有创建时完成创建;然后新建或获得WindowToken,并使用传进来的客户端窗口布局参数中的token值把WindowToken放入mTokenMap中;最后根据窗口能否能够接收键值更新焦点窗口。转自固弘博客
0 0
- ANDROID窗口管理服务实现机制
- ANDROID窗口管理服务实现机制
- ANDROID窗口管理服务实现机制
- ANDROID窗口管理服务实现机制
- android 窗口管理服务实现机制
- 第四篇 ANDROID窗口管理服务实现机制
- 第四篇 ANDROID窗口管理服务实现机制
- ANDROID窗口管理服务实现机制和架构分析
- 第四篇 ANDROID窗口管理服务实现机制 窗口管理是ANDROID框架一个重要部分,主要包括如下功能: (1)Z-ordered的维护 (2)窗口的创建、销
- ANDROID包管理服务机制 .
- Android 窗口管理服务WindowManagerService 简介
- Android提供的系统服务之--WindowManager(窗口管理服务)
- WindowManager(窗口管理服务)
- [Android实例] android的窗口机制分析------UI管理系统
- Android窗口管理服务WindowManagerService的简要介绍和学习计划
- Android窗口管理服务WindowManagerService的简要介绍
- Android窗口管理服务WindowManagerService的简要介绍和学习计划
- Android窗口管理服务相关对象的创建流程
- 怎样在VS2010中打开并编译VS2012的项目
- Posts Tagged 【List】Anagrams
- Android自定义progressDialog使用系统ProgressBar与图片实现(一)系统ProgressBar
- JAVA类加载器的获取
- Java基础——集合(三)——泛型、增强for、工具类
- android 窗口管理服务实现机制
- android点击组件震动
- Java Thread(线程)案例详解sleep和wait的区别
- gson和JavaBean之间的转换
- 博客线下推广的小技巧
- Android自定义progressDialog使用系统ProgressBar与图片实现(二)使用图片
- C Primer Plus 第九章课后习题……2015.5.1
- libevent中的信号处理
- android 事件分发和消费机制