Dialog创建依赖的Context对象必须是Activity吗?

很明显这个问题不是肯定的,是可以为其他的Context的。不然传参就定为了activity了。

先看下不传如activity基本的使用。一般用作悬浮窗。

AndroidManifest.xml 里面添加权限

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

检测在应用上层展示的权限是否开启

fun checkOverlayPermission(context: Context): Boolean {
        return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M)
            Settings.canDrawOverlays(context)
        else
            true 
    }

如果没有开启,则打开设置开启权限。不同的机型打开的方式可能不同。

startActivity(Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION, Uri.parse("package:$packageName")))

创建Dialog设置TYPE_APPLICATION_OVERLAY(8.0之前使用TYPE_ SYSTEM_ ALERT

val dialog = AlertDialog.Builder(this.applicationContext)
                .setTitle("title")
                .setMessage("message")
                .create()
            dialog.window?.setType(TYPE_APPLICATION_OVERLAY)
            dialog.show()

这样就完成了一个悬浮在应用上层的Dialog。

如果我把TYPE_APPLICATION_OVERLAY去掉,则会报异常BadTokenException

Token 的定义和作用

因为在WMS那边需要根据这个Token来确定Window的位置(不是说坐标),如果没有Token的话,就不知道这个窗口应该放到哪个容器上了;

大致就是添加window时的验证,就是IBinder中的token和添加window时的token对应才能添加成功。

Token的赋值
Window.class - adjustLayoutParamsForSubWindow(WindowManager.LayoutParams wp)

走到这一步的方式为:

Dialog.class -> show() -> 

WindowManagerImpl.class -> addView(@NonNull View view, @NonNull ViewGroup.LayoutParams params)

WindowManagerGlobal.class -> addView(View view, ViewGroup.LayoutParams params,
            Display display, Window parentWindow, int userId)
// 这一步是关键
...
if (parentWindow != null) {
            parentWindow.adjustLayoutParamsForSubWindow(wparams);
        } 
...

所以可以看出parentWindow 是否为空起了关键作用。

Activity 重写了getSystemService方法,自定义了WINDOW_SERVICE 类型的返回。

非Activity的Context得到的WindowManager没有parentWindow的,所以token无法对应就会异常。

添加TYPE_APPLICATION_OVERLAY的原因就是:
WMS在看到Window.TYPE 为 SYSTEM_WINDOW 时会为SYSTEM_WINDOW类型的窗口专门创建一个WindowToken,并放置在DisplayArea.Tokens里面

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值