WindowManager$BadTokenException-解决方案

简介

上一篇分析了WindowManager$BadTokenException发生的原因,带大家一起通过分析WindowManager源码,更加深入的了解了WindowManager添加window的过程,以及在使用WindowManager添加自己的window或者View的时候,怎么去避免发生异常,接下来,继续深入分析WindowManager源码,带大家一起寻找,解决平时使用WindowManager出现的各种异常的办法。

建 议 : \color{blue}{建议:} 本文章讲解,建立在上一篇文章的基础之上,所以阅读本文章前,请先阅读上一篇文章,地址如下:
WindowManager$BadTokenException(WindowManager源码分析

###源码版本
在没有特别说明的情况下,源码版本如下:

  • sdk:android-28

  • Android系统源码:Android8.0
    ###window类型
    Window有三种类型,分别是应用Window,子Window和系统Window。

  • 应用类Window对应着一个Activity。

  • 子Window不能单独存在,它需要附属在特定的父Window中,比如Dialog就是一个子Window。

  • 系统Window是需要声明权限才能创建的Window,比如Toast和系统状态栏这些都是系统Window。

    Window是分层的,每个Window都有对应的z-ordered,层级大的会覆盖    在层级小的Window上。在三类    
    Window中,应用Window的层级范围是1~99,子Window的层级范围是1000~1999,系统Window的层级范 
    围是2000~2999。很显然系统Window的层级是最大的,而且系统层级有很多值,一般我们可以选用 
    TYPE_SYSTEM_ERROR或者TYPE_SYSTEM_OVERLAY,另外重要的是要记得在清单文件中声明权限。
    

系统Window

由于源码比较多,只讲解关键或者不容易判断的代码,其它可以自行查看。

  • 函数 :addView(View view, ViewGroup.LayoutParams params,Display display, Window parentWindow)
    源码文件:WindowManagerGlobal.java
  1. root = new ViewRootImpl(view.getContext(), display);
    创建ViewRootImpl,看一下里面创建的几个关键的对象
    (1) mWindow = new W(this);
    (2) mWindowSession = WindowManagerGlobal.getWindowSession();
  • 函数:setView(View view, WindowManager.LayoutParams attrs, View panelParentView)
    源码文件:ViewRootImpl.java
  1. 参数变化:
    (1) attrs
    mWindowAttributes.copyFrom(attrs);
    if (mWindowAttributes.packageName == null) {
        mWindowAttributes.packageName = mBasePackageName;
    }
    attrs = mWindowAttributes;
    
  • 函数:addWindow(Session session, IWindow client, int seq,WindowManager.LayoutParams attrs, int viewVisibility, int displayId, Rect outContentInsets, Rect outStableInsets, Rect outOutsets,InputChannel outInputChannel)
  1. 参数
    (1)session: mWindowSession
    (2)client:mWindow
    (3)attrs:mWindowAttributes包含了传入时WindowManager.LayoutParams参数的所有属性

  2. 权限检测: int res = mPolicy.checkAddPermission(attrs, appOp)
    函数:checkAddPermission(WindowManager.LayoutParams attrs, int[] outAppOp)
    源码路径:frameworks/base/services/core/java/com/android/server/policy/PhoneWindowManager.java
    (1)如果不在window类型里,返回无效类型 —— ADD_INVALID_TYPE

     if (!((type >= FIRST_APPLICATION_WINDOW && type <
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值