bug_ _ android.view.WindowManager$BadTokenException: Unable to add window -- token

博客链接分享
`android.view.WindowManager$BadTokenException: Unable to add window -- token null is not valid; is your activity running?` 错误通常是由于在创建弹窗时使用了无效的上下文或上下文的生命周期问题导致的。以下是一些解决该问题的方法: #### 使用 Activity 上下文而非 Application 上下文 在创建弹窗时,不能使用 `getApplicationContext()`,因为应用程序上下文没有窗口令牌,弹窗需要依赖于 Activity 上下文。例如,将 `AlertDialog` 或 `ProgressDialog` 的上下文从 `getApplicationContext()` 改为 `Activity` 实例: ```java // 错误示例 new AlertDialog.Builder(getApplicationContext()) .setIcon(android.R.drawable.ic_dialog_alert) .setTitle("Warnning") .setPositiveButton("Yes", positiveListener) .setNegativeButton( "No", negativeListener) .create().show(); // 正确示例 new AlertDialog.Builder(YourActivity.this) .setIcon(android.R.drawable.ic_dialog_alert) .setTitle("Warnning") .setPositiveButton("Yes", positiveListener) .setNegativeButton( "No", negativeListener) .create().show(); ``` #### 确保 Activity 处于活动状态 在显示弹窗之前,要确保 Activity 是处于活动状态(如 `onResume()` 之后)。可以在 `onWindowFocusChanged` 或 `onResume` 等方法中显示弹窗: ```java @Override public void onWindowFocusChanged(boolean hasFocus) { super.onWindowFocusChanged(hasFocus); if (hasFocus && !isMainPopupShowing) { PopupWindowGroup.getInstance(YourActivity.this).showMainPopup(); isMainPopupShowing = true; } } ``` #### 检查 Service 中显示弹窗的方式 如果在 Service 中显示弹窗,要使用 `WindowManager` 并确保权限正确。如在 Service 中显示 Compose 弹窗的示例: ```kotlin import android.annotation.SuppressLint import android.app.Service import android.content.Intent import android.graphics.PixelFormat import android.os.Build import android.os.IBinder import android.view.Gravity import android.view.LayoutInflater import android.view.WindowManager import androidx.compose.ui.platform.ComposeView import androidx.compose.material.Text import androidx.compose.runtime.Composable class PopupService : Service() { private lateinit var windowManager: WindowManager private lateinit var composeView: ComposeView override fun onCreate() { super.onCreate() windowManager = getSystemService(WINDOW_SERVICE) as WindowManager composeView = ComposeView(this).apply { setContent { PopupContent() } } } @SuppressLint("InflateParams") override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int { val layoutParams = WindowManager.LayoutParams( WindowManager.LayoutParams.WRAP_CONTENT, WindowManager.LayoutParams.WRAP_CONTENT, if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY } else { WindowManager.LayoutParams.TYPE_PHONE }, WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE, PixelFormat.TRANSLUCENT ).apply { gravity = Gravity.TOP or Gravity.START } windowManager.addView(composeView, layoutParams) return START_STICKY } override fun onDestroy() { super.onDestroy() windowManager.removeView(composeView) } override fun onBind(intent: Intent?): IBinder? { return null } } @Composable fun PopupContent() { Text(text = "这是一个 Compose 弹窗") } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值