WMS简介:
WindowManagerService,即窗口管理服务,简称WMS。顾名思义,主要用于进行窗口的管理,通过WMS的数据成员就可以看出来;除了管理窗口外,WMS还要对事件进行管理和分发。
WMS可以作为一个系统服务,可以说是系统服务中最复杂的一个服务了,和AMS(ActivityManagerService)称为Android系统框架“双子星”。掌握了这两个服务的原理和使用方法,可以说,就掌握了Android系统框架的95%了。
WMS类图:
代码位置:
framworks/base/services/java/com/android/server/wm/WindowManagerService.java:
其中,只列出WMS部分数据成员和成员函数,说明如下:
//所有当前激活的客户端sessions,正是这些session来请求WMS的资源
final HashSet<Session> mSessions = new HashSet<Session>();//真正的窗口对象
final HashMap<IBinder, WindowState> mWindowMap = new HashMap<IBinder, WindowState>();//已经完成启动的应用列表
final ArrayList<AppWindowToken> mFinishedStarting = new ArrayList<AppWindowToken>();//渐变窗口列表
final ArrayList<FakeWindowImpl> mFakeWindows = new ArrayList<FakeWindowImpl>();//正在改变尺寸的窗口列表
final ArrayList<WindowState> mResizingWindows = new ArrayList<WindowState>();//动画结束并且马上被移除的窗口列表
final ArrayList<WindowState> mPendingRemove = new ArrayList<WindowState>();//surface马上要被释放的窗口列表
final ArrayList<WindowState> mDestroySurface = new ArrayList<WindowState>();//失去输入焦点并且等待新的焦点的窗口列表
ArrayList<WindowState> mLosingFocus = new ArrayList<WindowState>();
onTransact():用于进程间通信。作为服务,怎么能少了onTransact呢。
WMS的初始化:
和其它Framework层的许多service一样,WMS也是在system_server进程中启动的,WMS启动代码:
framworks/base/services/java/com/android/server/SystemServer.java:
wm = WindowManagerService.main(context, power,
factoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL,
!firstBoot, onlyCore);
ServiceManager.addService(Context.WINDOW_SERVICE, wm);
创建WMS实例,并且添加到service管理器中。注意,这段代码是在ServerThread的run函数中进行的,而且,wm是ServerThread线程的一个数据成员。整个AndroidFramework层的很多组件,都是ServerThread的数据成员,ServerThread是Framework的核心,而组成这个核心的是各个service。
WMS的实现:
framworks/base/services/java/com/android/server/wm/WindowManagerService.java:
从main函数开始来看:
public static WindowManagerService main(Context context,
PowerManagerService pm, boolean haveInputMethods, boolean allowBootMsgs,
boolean onlyCore) {
WMThread thr = new WMThread(context, pm, haveInputMethods, allowBootMsgs, onlyCore);
thr.start();
synchronized (thr) {
while (thr.mService == null) {
try {
thr.wait();
} catch (InterruptedException e) {
}
}
return thr.mService;
}
}
main函数返回的是本身这个对象,而且是通过线程WMThread返回的,也即WMThread这个线程创建的对象拥有WindowManagerService的实例的句柄。那么,主要看WMThread这个线程的实现(在源码中w,紧接着main函数的下面):w
static class WMThread extends Thread {
WindowManagerService mService;
private final Context mContext;
private final PowerManagerService mPM;
private final boolean mHaveInputMethods;
private final boolean mAllowBootMessages;
private final boolean mOnlyCore;
public WMThread(Context context, PowerManagerService pm,
boolean haveInputMethods, boolean allowBootMsgs, boolean onlyCore) {
super("WindowManager");
mContext = context;
mPM = pm;
mHaveInputMethods = haveInputMethods;
mAllowBootMessages = allowBootMsgs;
mOnlyCore = onlyCore;
}
@Override
public void run() {
Looper.prepare();
//Looper.myLooper().setMessageLogging(new LogPrinter(
// android.util.Log.DEBUG, TAG, android.util.Log.LOG_ID_SYSTEM));
WindowManagerService s = new WindowManagerService(mContext, mPM,
mHaveInputMethods, mAllowBootMessages, mOnlyCore);
android.os.Process.setThreadPriority(
android.os.Process.THREAD_PRIORITY_DISPLAY);
android.os.Process.setCanSelfBackground(false);
synchronized (this) {
mService = s;
notifyAll();
}
// For debug builds, log event loop stalls to dropbox for analysis.
if (StrictMode.conditionallyEnableDebugLogging()) {
Slog.i(TAG, "Enabled StrictMode logging for WMThread's Looper");
}
Looper.loop();
}
}
可以看到,WHThread是一个静态内部类,有一个WindowManagerService的数据成员。在这个线程的run方法中,调用了WindowManagerService的构造函数(哦,原来是在这里创建的WindowManagerService的实例),创建完成后,把这个实例就保存起来:
synchronized (this) {
mService = s;
notifyAll();
}
注意,这里用同步,一定得等到WindowManagerService的实例s被创建好之后,才能进行以上代码的执行。
接着,来看WindowManagerService的构造函数:
private WindowManagerService(Context context, PowerManagerService pm,
boolean haveInputMethods, boolean showBootMsgs, boolean onlyCore) {
mContext = context;
mHaveInputMethods = haveInputMethods;
mAllowBootMessages = showBootMsgs;
mOnlyCore = onlyCore;
mLimitedAlphaCompositing = context.getResources().getBoolean(
com.android.internal.R.bool.config_sf_limitedAlpha);
mHeadless = "1".equals(SystemProperties.get(SYSTEM_HEADLESS, "0"));
mPowerManager = pm;
mPowerManager.setPolicy(mPolicy);
PowerManager pmc = (PowerManager)context.getSystemService(Context.POWER_SERVICE);
mScreenFrozenLock = pmc.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK,
"SCREEN_FROZEN");
mScreenFrozenLock.setReferenceCounted(false);
mActivityManager = ActivityManagerNative.getDefault();
mBatteryStats = BatteryStatsService.getService();
// Get persisted window scale setting
mWindowAnimationScale = Settings.System.getFloat(context.getContentResolver(),
Settings.System.WINDOW_ANIMATION_SCALE, mWindowAnimationScale);
mTransitionAnimationScale = Settings.System.getFloat(context.getContentResolver(),
Settings.System.TRANSITION_ANIMATION_SCALE, mTransitionAnimationScale);
mAnimatorDurationScale = Settings.System.getFloat(context.getContentResolver(),
Settings.System.ANIMATOR_DURATION_SCALE, mTransitionAnimationScale);
// Track changes to DevicePolicyManager state so we can enable/disable keyguard.
IntentFilter filter = new IntentFilter();
filter.addAction(DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED);
mContext.registerReceiver(mBroadcastReceiver, filter);
mHoldingScreenWakeLock = pmc.newWakeLock(PowerManager.SCREEN_BRIGHT_WAKE_LOCK
| PowerManager.ON_AFTER_RELEASE, "KEEP_SCREEN_ON_FLAG");
mHoldingScreenWakeLock.setReferenceCounted(false);
mInputManager = new InputManagerService(context, mInputMonitor);
mAnimator = new WindowAnimator(this, context, mPolicy);
PolicyThread thr = new PolicyThread(mPolicy, this, context, pm);
thr.start();
synchronized (thr) {
while (!thr.mRunning) {
try {
thr.wait();
} catch (InterruptedException e) {
}
}
}
mInputManager.start();
// Add ourself to the Watchdog monitors.
Watchdog.getInstance().addMonitor(this);
mFxSession = new SurfaceSession();
Surface.openTransaction();
createWatermark();
Surface.closeTransaction();
}
在WindowManagerService的构造函数中,大部分代码都是在进行数据成员的初始化。WindowManagerService声明了大量的系统框架类的实例,例如:
mContext:运行环境上下文;
mPowerManager:电源管理相关;
mActivityManager:用于管理activity管理;
mInputManager:输入法相关;
mBatteryStats:电池状态相关;
除了初始化这些数据成员外,构造函数中,比较重要的代码如下:
注册了receiver:
IntentFilter filter = new IntentFilter();
//用于接收设备状态的变化 filter.addAction(DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED);
mContext.registerReceiver(mBroadcastReceiver, filter);//用于接收电源状态的变化
mHoldingScreenWakeLock = pmc.newWakeLock(PowerManager.SCREEN_BRIGHT_WAKE_LOCK
| PowerManager.ON_AFTER_RELEASE, "KEEP_SCREEN_ON_FLAG");
mHoldingScreenWakeLock.setReferenceCounted(false);
还创建了一个线程PolicyThread :
PolicyThread thr = new PolicyThread(mPolicy, this, context, pm);
thr.start();
和WMThread类似,这个线程也是一个静态内部类,它主要的作用是配合WindowManagerPolicy来完成整个Service功能的实现。
mInputManager.start(); //开启输入法
Surface.openTransaction(); //打开surface事务
至此,整个WMS就初始化完成了。
可以说,真个初始化过程要比上面的流程复杂的多,不可能面面俱到,仅抛砖引玉。
WMS的使用:
在Android应用程序开发时,是通过WindowManager来访问WMS提供的服务的。
例如,获取WindowManager的代码如下:
WindowManager wm = (WindowManager)getSystemService(Context.WINDOW_SERVICE);
给一个Activity动态添加一个Button的代码如下:
WindowManager wm = (WindowManager)getSystemService(Context.WINDOW_SERVICE);
Button btnView = new Button(this);
btnView.setText("Hello WM!");
WindowManager.LayoutParams mParams = new WindowManager.LayoutParams();
wm.addView(btnView, mParams);