Process: 包名, PID: 27541
android.view.WindowManager$BadTokenException: Unable to add window -- token null is not valid; is your activity running?
at android.view.ViewRootImpl.setView(ViewRootImpl.java:980)
at android.view.WindowManagerGlobal.addView(WindowManagerGlobal.java:398)
at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:96)
报错描述: 通过在当前Service服务中动态wm.addView(view, lp) 添加一个window窗口。执行时报错,错误信息如上面代码片。该服务Service启动于MainAcitivity并作为前台服务一直处于保活状态。
创建窗口代码
import android.content.Context
import android.graphics.PixelFormat
import android.os.Build
import android.util.Log
import android.view.Gravity
import android.view.View
import android.view.WindowManager
object WindowCreated {
private lateinit var context: Context
private lateinit var wm: WindowManager
private lateinit var lp: WindowManager.LayoutParams
fun initWindow(context: Context) {
this.context = context
this.wm = context.getSystemService(Context.WINDOW_SERVICE) as WindowManager
lp = createLayoutParams()
}
fun createLayoutParams(): WindowManager.LayoutParams {
val lp = WindowManager.LayoutParams()
lp.apply {
this.width = WindowManager.LayoutParams.MATCH_PARENT
this.height = WindowManager.LayoutParams.MATCH_PARENT
gravity = Gravity.CENTER
format = PixelFormat.TRANSLUCENT
flags = WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL or
WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE or
WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON or
WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS
type = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O)
WindowManager.LayoutParams.TYPE_ACCESSIBILITY_OVERLAY
else
WindowManager.LayoutParams.TYPE_PHONE
}
return lp
}
fun getView(layoutId: Int): View {
return View.inflate(context, layoutId, null)
}
fun showWindowView(view: View) {
Log.e("=====com.wensi显示窗口=====", view.toString())
if (view.parent == null) {
wm.addView(view, lp)
}
}
fun showWindowView(view: View, lp: WindowManager.LayoutParams) {
if (view.parent == null) {
wm.addView(view, lp)
}
}
fun hideWindowView(view: View) {
if (view.parent == null) {
wm.removeView(view)
}
}
fun updateWindowView(view: View, lp: WindowManager.LayoutParams) {
wm.updateViewLayout(view, lp)
}
}
之后在Service服务方法override fun onCreate() 中初始化窗口及布局
WindowCreated.initWindowHelper(this)
fullWindowView = WindowCreated.getView(R.layout.layout_window_item)
然后通过用户触发事件激活并添加窗口 WindowCreated.showWindowView(fullWindowView) 但执行后报错。后来经过逐步排查,窗口权限已添加且申请
protected fun requestWindowPermission(packageName: String) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
startActivityForResult(
Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION, Uri.parse("package:$packageName")),
codeWindowPermission)
}
}
排查方向不对: 业务逻辑代码也无问题,即不存在popWindow 初始化显示窗口过早问题。 排查方向不对: 为避免出现类似new AlertDialog.Builder(context) 一样的问题,尝试将context指向Activity。
后经过查看源码即第37行布局属性发现了问题:(不小心赋值变量错误导致) 应用必须使用名为TYPE_APPLICATION_OVERLAY 的新窗口, 而不是TYPE_ACCESSIBILITY_OVERLAY 。
|