Window
WindowManagerService
位于 Framework 层的窗口管理服务,管理系统中的所有窗口
窗口(Window):一块显示区域,在 Android 中就是绘制的画布。VIew为Window的实体,Window是一个抽象概念
可独立完成对Window的操作, 作为系统级服务运行在一个单独的进程。因此,WindowManager 和 WindowManagerService 的交互是一个 IPC 过程
![](Android 的显示系统.png)
Window 分类
应用 Window :对应一个 Acitivity,层级范围:1~99
子 Window :子 Window 不能单独存在,需要依附在特定的父 Window 中,如Dialog。层级范围:1000~1999
系统 Window :创建需要声明权限,如Toast和系统栏状态。层级范围:2000~2999
WindowManager
机制
interface ViewManager
interface WindowManager
class WindowManagerImpl
//ViewManager接口只提供三个view的功能操作
public interface ViewManager{
//添加view
public void addView(View view, ViewGroup.LayoutParams params);
//更新view
public void updateViewLayout(View view, ViewGroup.LayoutParams params);
//删除view
public void removeView(View view);
}
//WindowManagerImpl
private class WindowManagerImpl{
...
//未直接实现对view的具体操作,而是交给WindowManagerGlobal来处理
@Override public void addView(View view, ViewGroup.LayoutParams params){
mGlobal.addView(view, params, mDisplay, mParentWindow);
}
@Override public void updateViewLayout(View view, ViewGroup.LayoutParams params){
mGlobal.updateViewLayout(view, params);
}
@Override public void removeView(View view){
mGlobal.removeView(view, false);
}
}
//WindowManagerGlobal的实现过程
private class WindowManagerGlobal{
//Window 所对应的 View
private final ArrayList<View> mViews = new ArrayList<View>();
//Window 所对应的 ViewRootImpl
private final ArrayList<ViewRootImpl> mRoots = new ArrayList<ViewRootImpl>();
//Window 所对应的布局参数
private final ArrayList<WindowManager.LayoutParams> mParams = new ArrayList<WindowManager.LayoutParams>();
//正在被删除的 View 对象
private final ArraySet<View> mDyingViews = new ArraySet<View>();
public void addView(...){
//ViewRootImpl是view绘制流程的起点,通过setView()实现,setView()内部调用requestLayout()异步刷新请求
root = new ViewRootImpl(view.getContext(),display);
view.setLayoutParams(wparams);
//将相关对象添加到对应集合中
mViews.add(view);
mRoots.add(root);
mParams.add(wparams);
}
}
//异步刷新请求
public void requestLayout(){
if(!mHandingLayoutInLayoutRequest){
checkThread();
mLayoutRequested = true;
scheduleTraversals();
}
}
public void scheduleTraversals(){
//mWindowSession类型为IWindowSession,是一个Binder对象,其实现类为Session。Session内部通过WindowManagerService来实现Window的添加
res = mWindowSession.addToDisplay(mWindow, mSeq, mWindowAttributes, getHostVisibility(),
mDisplay.getDisplayId(),mAttachInfo.mContentInsets, mInputChannel);
}
//WindowManagerService添加window
public int addToDisplay(IWindow window, int seq, WindowManager.LayoutParams, attrs, int viewVisibility, int displayId, Rect outContentInsets, InputChannel outInputChannel){
//mService类型为WindManageService,最终在WindManageService中添加了window
return mService.addWindow(this, window, seq, attrs, viewVisibility, displayId, outContentInsets, outInputChannel);
}
举例
//添加权限
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/>
//通过WindowManager添加Window
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Button floatingButton = new Button(this);
floatingButton.setText("button");
WindowManager.LayoutParams layoutParams = new WindowManager.LayoutParams(
WindowManager.LayoutParams.WRAP_CONTENT,
WindowManager.LayoutParams.WRAP_CONTENT,
0, 0,
PixelFormat.TRANSPARENT
);
// flag 设置 Window 属性
layoutParams.flags= WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL;
// type 设置 Window 类别(层级)
layoutParams.type = WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY;
layoutParams.gravity = Gravity.CENTER;
WindowManager windowManager = getWindowManager();
windowManager.addView(floatingButton, layoutParams);
}
}