View树与Window关联
前面介绍的是View树的创建,但是创建好的View树只有添加到一个Window里才会显示到屏幕上,因为WindowManagerService
服务会为每一个Window创建一块Surface作为画布,View树里所有的View都会绘画到这块Surface上,最后SurfaceFlinger
服务会将所有Window创建的的Surface传递给GPU,最终显示到屏幕上。
创建Window
通过WindowManager.addView
接口就可以申请创建一个新的Window并添加一个View树,弹出菜单、浮动窗口等自定义的窗口都是通过这个接口显示出来的:
//获得WindowManager服务
WindowManager windowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
//设置Window参数
WindowManager.LayoutParams params = new WindowManager.LayoutParams();
params.setTitle("FloatWindow");
//创建View树
View rootView = getLayoutInflater().inflate(R.layout.float_layout, null);
//创建Window并关联View树
windowManager.addView(rootView, params);
应用中使用的WindowManager
其实是一个WindowManagerImpl
类的实例:
frameworks/base/core/java/android/view/WindowManagerImpl.java
public final class WindowManagerImpl implements WindowManager {
private final WindowManagerGlobal mGlobal = WindowManagerGlobal.getInstance();
private final Context mContext;
private final Window mParentWindow;
...
@Override
public void addView(@NonNull View view, @NonNull ViewGroup.LayoutParams params) {
applyDefaultToken(params);
mGlobal.addView(view, params, mContext.getDisplay(), mParentWindow);
}
}
如上面的代码,WindowManagerImpl.addView()
实现会调用WindowManagerGlobal.addView()
,实际的请求创建Window的逻辑也在这个类里实现:
frameworks/base/core/java/android/view/WindowManagerGlobal.java
public final class WindowManagerGlobal {
private final ArrayList<View> mViews = new ArrayList<