第八章理解Window和WindowManager(Android开发艺术探索)

本文详细解析了Android中Window和WindowManager的工作机制,包括添加、删除和更新Window的流程,以及Activity、Dialog和Toast的Window创建过程。讲解了Window的层级管理,强调了WindowManager在操作Window时的角色,以及涉及的IPC通信和权限管理。
摘要由CSDN通过智能技术生成

8.1、window和windowManager

为了分析window的工作机制,我们需要先了解如何使用windowManager添加一个window

代码如下:

WindowManager manager = (WindowManager) getSystemService(Context.WINDOW_SERVICE);
WindowManager.LayoutParams layoutParams = new WindowManager.LayoutParams(width,height,type,flags,format);
manager.addView(btn, layoutParams);

是不是很简单的说?

LayoutParams中type和flags比较重要

flags有很多选项,来控制window的显示特性,我们看几个常用的

public static final int FLAG_NOT_FOCUSABLE      = 0x00000008;
表示此window不需要获取焦点,不接收各种输入事件,此标记是会同时启用FLAG_NOT_TOUCH_MODAL    
最终事件会直接传递给下层具有焦点的window
public static final int FLAG_NOT_TOUCH_MODAL    = 0x00000020;
自己window区域内的事件,自己处理;自己区域外的事件传递给底层window处理;
一般这个都会默认开启,不然其他window无法收到事件
public static final int FLAG_SHOW_WHEN_LOCKED = 0x00080000;
可以让此window显示在锁屏上

type表示window的类型,window有3种类型,应用window,子window,系统window

window是分层的,层级大的view会覆盖在层级小的view上面

应用window的层级范围:1~99
子window的层级范围:1000~1999
系统window的层级范围:2000~2999

这些层级返回对应type参数,如果想要window至于最顶层,采用较大的层级即可

同时如果是系统类型的window是需要在menifest中配置权限的:

<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />

下面我们来看看windowManager:

它是一个接口,继承ViewManager:

public interface WindowManager extends ViewManager {
   

ViewManager中只有3个方法:
public interface ViewManager
{
   
    public void addView(View view, ViewGroup.LayoutParams params);
    public void updateViewLayout(View view, ViewGroup.LayoutParams params);
    public void removeView(View view);
}

根据方法名称就可以知道是对view的增加、修改、删除

8.2、window的内部机制

每个window都对应一个view和viewrootimpl

8.2.1、window的添加过程

window的添加是通过windowManager来实现的
windowManager是一个接口,它的实现类是:windowManagerImpl

我们来看看WindowManagerImpl这个类:
找到了我们需要的方法:

public final class WindowManagerImpl implements WindowManager {
   
    private final WindowManagerGlobal mGlobal = WindowManagerGlobal.getInstance();
@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);
}
}

我们可以看到它是利用了工厂类WindowManaerGlobal来实现的

WindowManaerGlobal实现addview分如下几步:

1、检查参数是否合法,如果是子window,那么还需要调整一些布局参数

if (view == null) {
    throw new IllegalArgumentException("view must not be null");
}
if (display == null) {
    throw new IllegalArgumentException(
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值