Andrid概念——Window全认识(持续更新)

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);
    }
}

猜你喜欢

转载自blog.csdn.net/mLuoya/article/details/87902434