从图1还可以看出,每一个Activity组件在ActivityManagerService服务内部,都对应有一个ActivityRecord对象,这个ActivityRecord对象是Activity组件启动的过程中创建的,用来描述Activity组件的运行状态,这一点可以参考前面Android应用程序启动过程源代码分析一文。这样,每一个Activity组件在应用程序进程、WindowManagerService服务和ActivityManagerService服务三者之间就分别一一地建立了连接。在本文中,我们主要关注Activity组件在应用程序进程和WindowManagerService服务之间以及在WindowManagerService服务和ActivityManagerService服务之间的连接。
final void handleResumeActivity(IBinder token, boolean clearHide, boolean isForward) {
getWindowManager
当应用程序进程启动第一个Activity组件的时候,就会请求WindowManagerService服务发送一个建立连接的Binder进程间通信请求。
wm.addView(decor, l);
public class WindowManagerImpl implements WindowManager {
......
public void addView(View view, ViewGroup.LayoutParams params)
{
WindowManagerGlobal
public void addView(View view, ViewGroup.LayoutParams params,
Display display, Window parentWindow) {
root = new ViewRootImpl(view.getContext(), display);
public class Activity extends ContextThemeWrapper
Activity ActivityManagerService WindowManagerService
ViewRootImpl
public final class ViewRootImpl implements ViewParent,
final IWindowSession mWindowSession;
public ViewRootImpl(Context context, Display display) {
mContext = context;
mWindowSession = WindowManagerGlobal.getWindowSession();
WindowManagerGlobal (代理IWindowManager)
public static IWindowSession getWindowSession() {
private static IWindowSession sWindowSession;
IWindowManager windowManager = getWindowManagerService();
sWindowSession = windowManager.openSession(
new IWindowSessionCallback.Stub() {
if (sWindowManagerService == null) {
sWindowManagerService = IWindowManager.Stub.asInterface(
ServiceManager.getService("window"));
}
return sWindowManagerService;
IWindowManager.Stub.asInterface ServiceManager.getService("window")
WindowManagerService(本地 IWindowManager)
@Override
public IWindowSession openSession(IWindowSessionCallback callback, IInputMethodClient client,
IInputContext inputContext) {
Session session = new Session(this, callback, client, inputContext);
代理
IWindowSession
final class Session extends IWindowSession.Stub
Session
@Override
public int add(IWindow window, int seq, WindowManager.LayoutParams attrs,
IWindowSession
public interface IWindowSession extends android.os.IInterface
Stub(本地Session实例)
public static abstract class Stub extends android.os.Binder implements android.view.IWindowSession
@Override public boolean onTransact(int code, android.os.Parcel data, android.os.Parcel reply, int flags) throws android.os.RemoteException
{
switch (code)
{
case INTERFACE_TRANSACTION:
{
reply.writeString(DESCRIPTOR);
return true;
}
case TRANSACTION_add:
{
data.enforceInterface(DESCRIPTOR);
Proxy(代理Session实例)
private static class Proxy implements android.view.IWindowSession
{
private android.os.IBinder mRemote;
Proxy(android.os.IBinder remote)
{
mRemote = remote;
}
@Override public int add(android.view.IWindow window, int seq, android.view.WindowManager.LayoutParams attrs, int viewVisibility, android.graphics.Rect outContentInsets, android.view.InputChannel outInputChannel) throws android.os.RemoteException
{
mRemote.transact(Stub.TRANSACTION_add, _data, _reply, 0);
public class WindowManagerService extends IWindowManager.Stub
final class Session extends IWindowSession.Stub
ViewRoot
public final class ViewRoot extends Handler implements ViewParent,
public void setView(View view, WindowManager.LayoutParams attrs,
res = sWindowSession.add(mWindow, mWindowAttributes,
getHostVisibility(), mAttachInfo.mContentInsets,
mInputChannel);
public final class ViewRoot extends Handler implements ViewParent,
View.AttachInfo.Callbacks {
......
static IWindowSession sWindowSession;
......
final W mWindow;
View mView;
......
public ViewRoot(Context context) {
super();
......
mWindow = new W(this, context);
......
}
......
public void setView(View view, WindowManager.LayoutParams attrs,
View panelParentView) {
synchronized (this) {
if (mView == null) {
mView = view;
......
try {
res = sWindowSession.add(mWindow, mWindowAttributes,
getHostVisibility(), mAttachInfo.mContentInsets,
mInputChannel);
} catch (RemoteException e) {
......
} finally {
......
}
......
}
......
}
}
......
}
WindowManagerService IWindowSession
dispatch windowAddedLocked
AppWindowToken WindowState
public class ActivityStack {
final ActivityManagerService mService;
private final void startActivityLocked(ActivityRecord r, boolean newTask,
mService.mWindowManager.addAppToken(addPos, r, r.task.taskId,
mTokenList mTokenMap
由于参数token描述的是一个Activity组件窗口,因此,函数就会为它创建一个AppWindowToken对象,
atoken = new AppWindowToken(this, token, voiceInteraction);
WindowManagerService
AppWindowToken
Activity
ActivityManagerService ActivityRecord
WindowManagerImpl(实现类) addView
public class WindowManagerService extends IWindowManager.Stub
implements Watchdog.Monitor, WindowManagerPolicy.WindowManagerFuncs {
ActivityRecord = AppWindowToken
WindowState
WindowManagerService服务和ActivityManagerService服务三者之间就分别一一地建立了连接。在本文中,我们主要关注Activity组件在应用程序进程和WindowManagerService服务之间以及在WindowManagerService服务和ActivityManagerService服务之间的连接。
final void handleResumeActivity(IBinder token, boolean clearHide, boolean isForward) {
getWindowManager
当应用程序进程启动第一个Activity组件的时候,就会请求WindowManagerService服务发送一个建立连接的Binder进程间通信请求。
wm.addView(decor, l);
public class WindowManagerImpl implements WindowManager {
......
public void addView(View view, ViewGroup.LayoutParams params)
{
WindowManagerGlobal
public void addView(View view, ViewGroup.LayoutParams params,
Display display, Window parentWindow) {
root = new ViewRootImpl(view.getContext(), display);
public class Activity extends ContextThemeWrapper
Activity ActivityManagerService WindowManagerService
ViewRootImpl
public final class ViewRootImpl implements ViewParent,
final IWindowSession mWindowSession;
public ViewRootImpl(Context context, Display display) {
mContext = context;
mWindowSession = WindowManagerGlobal.getWindowSession();
WindowManagerGlobal (代理IWindowManager)
public static IWindowSession getWindowSession() {
private static IWindowSession sWindowSession;
IWindowManager windowManager = getWindowManagerService();
sWindowSession = windowManager.openSession(
new IWindowSessionCallback.Stub() {
if (sWindowManagerService == null) {
sWindowManagerService = IWindowManager.Stub.asInterface(
ServiceManager.getService("window"));
}
return sWindowManagerService;
IWindowManager.Stub.asInterface ServiceManager.getService("window")
WindowManagerService(本地 IWindowManager)
@Override
public IWindowSession openSession(IWindowSessionCallback callback, IInputMethodClient client,
IInputContext inputContext) {
Session session = new Session(this, callback, client, inputContext);
代理
IWindowSession
final class Session extends IWindowSession.Stub
Session
@Override
public int add(IWindow window, int seq, WindowManager.LayoutParams attrs,
IWindowSession
public interface IWindowSession extends android.os.IInterface
Stub(本地Session实例)
public static abstract class Stub extends android.os.Binder implements android.view.IWindowSession
@Override public boolean onTransact(int code, android.os.Parcel data, android.os.Parcel reply, int flags) throws android.os.RemoteException
{
switch (code)
{
case INTERFACE_TRANSACTION:
{
reply.writeString(DESCRIPTOR);
return true;
}
case TRANSACTION_add:
{
data.enforceInterface(DESCRIPTOR);
Proxy(代理Session实例)
private static class Proxy implements android.view.IWindowSession
{
private android.os.IBinder mRemote;
Proxy(android.os.IBinder remote)
{
mRemote = remote;
}
@Override public int add(android.view.IWindow window, int seq, android.view.WindowManager.LayoutParams attrs, int viewVisibility, android.graphics.Rect outContentInsets, android.view.InputChannel outInputChannel) throws android.os.RemoteException
{
mRemote.transact(Stub.TRANSACTION_add, _data, _reply, 0);
public class WindowManagerService extends IWindowManager.Stub
final class Session extends IWindowSession.Stub
ViewRoot
public final class ViewRoot extends Handler implements ViewParent,
public void setView(View view, WindowManager.LayoutParams attrs,
res = sWindowSession.add(mWindow, mWindowAttributes,
getHostVisibility(), mAttachInfo.mContentInsets,
mInputChannel);
ViewRoot
IWindowSession
W
sWindowSession.add
public final class ViewRoot extends Handler implements ViewParent,
View.AttachInfo.Callbacks {
......
static IWindowSession sWindowSession;
......
final W mWindow;
View mView;
......
public ViewRoot(Context context) {
super();
......
mWindow = new W(this, context);
......
}
......
public void setView(View view, WindowManager.LayoutParams attrs,
View panelParentView) {
synchronized (this) {
if (mView == null) {
mView = view;
......
try {
res = sWindowSession.add(mWindow, mWindowAttributes,
getHostVisibility(), mAttachInfo.mContentInsets,
mInputChannel);
} catch (RemoteException e) {
......
} finally {
......
}
......
}
......
}
}
......
}
public final class ViewRootImpl implements ViewParent,
static class W extends IWindow.Stub {
private final WeakReference
private final IWindowSession mWindowSession;
ViewRoot
setView
mWindowSession = WindowManagerGlobal.getWindowSession();
mWindowSession.add
WindowManagerService
public int addWindow(Session session, IWindow client, int seq,
WindowManager.LayoutParams attrs, int viewVisibility, int displayId,
Rect outContentInsets, Rect outStableInsets, Rect outOutsets,
就会通过前面所获得一个Session代理对象来传递给WindowManagerService服务,
而WindowManagerService服务接收到这个W对象之后,
就会在内部创建一个WindowState对象来描述与该W对象所关联的Activity组件的窗口状态,
并且以后就通过这个W对象来控制对应的Activity组件的窗口状态。
应用程序进程就可以通过保存在ViewRoot类的静态成员变量sWindowSession所描述的一个Session代理对象所实现的IWindowSession接口来与WindowManagerService服务通信,
例如:
WindowManagerService
public int addWindow(Session session, IWindow client, int seq,
WindowManager.LayoutParams attrs, int viewVisibility, int displayId,
Rect outContentInsets, Rect outStableInsets, Rect outOutsets,
InputChannel outInputChannel) {
1. 在Activity组件的启动过程中,调用这个IWindowSession接口的成员函数add可以将一个关联的W对象传递到WindowManagerService服务,以便WindowManagerService服务可以为该Activity组件创建一个WindowState对象。
2. 在Activity组件的销毁过程中,调用这个这个IWindowSession接口的成员函数remove来请求WindowManagerService服务之前为该Activity组件所创建的一个WindowState对象,这一点可以参考前面Android应用程序键盘(Keyboard)消息处理机制分析一文的键盘消息接收通道注销过程分析。
3. 在Activity组件的运行过程中,调用这个这个IWindowSession接口的成员函数relayout来请求WindowManagerService服务来对该Activity组件的UI进行布局,以便该Activity组件的UI可以正确地显示在屏幕中。
WindowState
,后者于是就会得到一个W代理对象,
并且会以这个W代理对象来创建一个WindowState对象,即将这个W代理对象保存在新创建的WindowState对象的成员变量mClient中
W IWindow.Stub
final IWindow mClient;
WindowManagerService extends IWindowManager.Stub
Session extends IWindowSession.Stub(Stub Binder本地)
Stub(本地) Impl(实现类) Proxy(代理)
attach
WindowManagerService
addWindow
public int addWindow(Session session, IWindow client, int seq,
WindowState attachedWindow = null;
attachedWindow = windowForClientLocked(null, attrs.token, false);
WindowState win = mWindowMap.get(client);
final HashMap
token = new WindowToken(this, attrs.token, -1, false);
WindowToken(WindowManagerService _service, IBinder _token, int type, boolean _explicit) {
service = _service;
token = _token;
windowType = type;
explicit = _explicit;
}
WindowState win = new WindowState(this, session, client, token,
attachedWindow, appOp[0], seq, attrs, viewVisibility, displayContent);
if (addToken) {
mTokenMap.put(attrs.token, token);
}
win.attach();
mWindowMap.put(client.asBinder(), win);
void attach() {
if (WindowManagerService.localLOGV) Slog.v(
TAG, "Attaching " + this + " token=" + mToken
+ ", list=" + mToken.windows);
mSession.windowAddedLocked();
}
public class WindowManagerService extends IWindowManager.Stub
implements Watchdog.Monitor {
......
private final class WindowState implements WindowManagerPolicy.WindowState {
......
WindowState(Session s, IWindow c, WindowToken token,
WindowState attachedWindow, WindowManager.LayoutParams a,
int viewVisibility) {
mSession = s;
mClient = c;
mToken = token;
mAttrs.copyFrom(a);
mViewVisibility = viewVisibility;
DeathRecipient deathRecipient = new DeathRecipient();
mAlpha = a.alpha;
WindowManagerService IWindowManager.Stub
WindowState WindowManagerPolicy.WindowState
-mSession:指向一个类型为Session的Binder本地对象,使用参数s来初始化,表示当前所创建的WindowState对象是属于哪一个应用程序进程的。
-mClient:指向一个实现了IWindow接口的Binder代理对象,它引用了运行在应用程序进程这一侧的一个类型为W的Binder本地对象,使用参数c来初始化,通过它可以与运行在应用程序进程这一侧的Activity组件进行通信。
-mToken:指向一个WindowToken对象,使用参数token来初始化,通过它就可以知道唯一地标识一个窗口。
-mAttrs:指向一个WindowManager.LayoutParams对象,使用参数a来初始化,通过它就可以知道当前当前所创建的WindowState对象所描述的窗口的布局参数。
-mViewVisibility:这是一个整型变量,使用参数viewVisibility来初始化,表示当前所创建的WindowState对象所描述的窗口视图的可见性。
-mAlpha:这是一个浮点数,使用参数a所描述的一WindowManager.LayoutParams对象的成员变量alpha来初始化,表示当前所创建的WindowState对象所描述的窗口的Alpha通道。
WindowState appWin = this;
while (appWin.mAttachedWindow != null) {
appWin = mAttachedWindow;
}
WindowToken appToken = appWin.mToken;
while (appToken.appWindowToken == null) {
WindowToken parent = mTokenMap.get(appToken.token);
if (parent == null || appToken == parent) {
break;
}
appToken = parent;
}
mRootToken = appToken;
mAppToken = appToken.appWindowToken;
WindowState mAttachedWindow WindowToken appWindowToken
WindowToken appToken appWindowToken
public class WindowManagerService extends IWindowManager.Stub
implements Watchdog.Monitor {
private final class Session extends IWindowSession.Stub
void windowAddedLocked() {
if (mSurfaceSession == null) {
......
mSurfaceSession = new SurfaceSession();
......
mSessions.add(this);
}
mNumWindow++;
}
WindowManagerService IWindowManager.Stub
Session IWindowSession.Stub
mSurfaceSession = new SurfaceSession
mSessions.add(this);
static void SurfaceSession_init(JNIEnv* env, jobject clazz)
{
sp
client->incStrong(clazz);
env->SetIntField(clazz, sso.client, (int)client.get());
}
sp
struct sso_t {
jfieldID client;
};
static sso_t sso;
它是一个类型为sso_t的结构体变量,它的成员变量client描述的是SurfaceSession类的成员变量mClient在SurfaceSession类中的偏移量:
void nativeClassInit(JNIEnv* env, jclass clazz)
{
......
jclass surfaceSession = env->FindClass("android/view/SurfaceSession");
sso.client = env->GetFieldID(surfaceSession, "mClient", "I");
......
}
env->FindClass() env-GetFieldID surfaceSession mClient
mRootToken
至此,我们也分析完成Android应用程序窗口与WindowManagerService服务的连接过程了。从这个连接过程以及前面Android应用程序窗口(Activity)的窗口对象(Window)的创建过程分析和Android应用程序窗口(Activity)的视图对象(View)的创建过程分析这两篇文章,我们就可以知道,为了实现一个Activity组件的UI,无论是应用程序进程,还是WindowManagerService,都做了大量的工作,例如,应用程序进程为它创建一个窗口(Window)对象、一个视图(View)对象、一个ViewRoot对象、一个W对象,WindowManagerService服务为它创建一个AppWindowToken对象和一个WindowState对象。此外,WindowManagerService服务还为一个Activity组件所运行在的应用程序进程创建了一个Session对象。理解这些对象的实现以及作用对我们了解Android应用程序窗口的实现框架以及WindowManagerService服务的实现原理都是非常重要的。
虽然到目前为止,我们已经为Android应用程序窗口创建了很多对象,但是我们仍然还有一个最重要的对象还没有创建,那就是Android应用程序窗口的绘图表面,即用来渲染UI的Surface还没有创建。从前面Android应用程序与SurfaceFlinger服务的关系概述和学习计划这一系列的文章可以知道,这个Surface是要请求SurfaceFlinger服务来创建的,因此,在接下来的一篇文章中,我们就将继续分析Android应用程序窗口的绘图表面(Surface)的创建过程,敬请关注!