注:本文参考《深入理解Android内核设计思想》10.3节窗口的添加过程
窗口添加分两类:service和activity窗口添加,先以systemUI中的statusbar作为例子说明大致过程,然后再分析activity的不同。
一:状态栏的添加
在statusbarview.java中
private void addStatusBarWindow() {
// Put up the view
final int height = getStatusBarHeight();
// Now that the status bar window encompasses the sliding panel and its
// translucent backdrop, the entire thing is made TRANSLUCENT and is
// hardware-accelerated.
final WindowManager.LayoutParams lp = new WindowManager.LayoutParams(
ViewGroup.LayoutParams.MATCH_PARENT,
height,
WindowManager.LayoutParams.TYPE_STATUS_BAR,
WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
| WindowManager.LayoutParams.FLAG_TOUCHABLE_WHEN_WAKING
| WindowManager.LayoutParams.FLAG_SPLIT_TOUCH
| WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH,
PixelFormat.TRANSLUCENT);
lp.gravity = getStatusBarGravity();
lp.setTitle("StatusBar");
lp.packageName = mContext.getPackageName();
makeStatusBarView();//创建一个view
mWindowManager.addView(mStatusBarWindow, lp);
}
接下来看看这个mWindowManager是什么,addView是什么
mWindowManager = (WindowManager)mContext.getSystemService(Context.WINDOW_SERVICE);
在Contextimpl.java中
@Override
public Object getSystemService(String name) {
ServiceFetcher fetcher = SYSTEM_SERVICE_MAP.get(name);
return fetcher == null ? null : fetcher.getService(this);
}
SYSTEM_SERVIEC_MAP是一个Map
private static final HashMap<String, ServiceFetcher> SYSTEM_SERVICE_MAP =
new HashMap<String, ServiceFetcher>();
以服务名为key,servicefetcher为元素。猜测是放置了WINDOW_SERVICE。
registerService(WINDOW_SERVICE, new ServiceFetcher() {
Display mDefaultDisplay;
public Object getService(ContextImpl ctx) {
Display display = ctx.mDisplay;
if (display == null) {
if (mDefaultDisplay == null) {
DisplayManager dm = (DisplayManager)ctx.getOuterContext().
getSystemService(Context.DISPLAY_SERVICE);
mDefaultDisplay = dm.getDisplay(Display.DEFAULT_DISPLAY);
}
display = mDefaultDisplay;
}
return new WindowManagerImpl(display);
}});
通过registerService将WINDOW_SERVICE放入了SYSTEM_SERVICE_MAP中,其实可以看出,最后获得的mWindowManager其实是一个WindowManagerImpl,并且这个WindowManagerImpl是在systemUI进程中的,进入其addView方法:
@Override
public void addView(View view, ViewGroup.LayoutParams params) {
mGlobal.addView(view, params, mDisplay, mParentWindow);
}
调用mGlobal的addView方法,继续跟
private final WindowManagerGlobal mGlobal = WindowManagerGlobal.getInstance();
可知,其为单例模式,进程唯一的。
private WindowManagerGlobal() {
}
public static WindowManagerGlobal getInstance() {
synchronized (WindowManagerGlobal.class) {
if (sDefaultWindowManager == n