android.view.WindowManager$BadTokenException: Unable to add window -- token null is not for an appli

本文解决了在Android应用中创建对话框时出现的BadTokenException问题。错误源于使用了不正确的上下文对象来构建AlertDialog。正确的做法是使用Activity实例而非Application上下文。

原博客地址:http://aijiawang-126-com.javaeye.com/blog/662336

在Activity中newSpinner是我把mContext传入,但是出了android.view.WindowManager$BadTokenException: Unable to add window -- token null is not for an application这个错误,参考了达人的文章终于搞定。

  1. private Context mcontext; 
  2.     @Override 
  3.     protected void onCreate(Bundle savedInstanceState) {mcontext = getApplicationContext(); 
  4.         System.out.println("mcontext=" + mcontext); 
  5.     } 

  1. new AlertDialog.Builder(mcontext) 
  2.             .setIcon(android.R.drawable.ic_dialog_alert) 
  3.             .setTitle("Warnning"
  4.             .setMessage( 
  5.                     "You forget to write the message. Do you want to fill out it ??"
  6.             .setPositiveButton("Yes", positiveListener).setNegativeButton( 
  7.                     "No", negativeListener).create().show(); 

导致报这个错是在于new AlertDialog.Builder(mcontext),虽然这里的参数是AlertDialog.Builder(Context context)但我们不能使用getApplicationContext()获得的Context,而必须使用Activity,因为只有一个Activity才能添加一个窗体。

解决方法:将new AlertDialog.Builder(Context context)中的参数用Activity.this(Activity是你的Activity的名称)来填充就可以正确的创建一个Dialog了。

  1. new AlertDialog.Builder(MyActivity.this
  2.                 .setIcon(android.R.drawable.ic_dialog_alert) 
  3.                 .setTitle("Warnning"
  4.                 .setMessage( 
  5.                         "You forget to write the message. Do you want to fill out it ??"
  6.                 .setPositiveButton("Yes", positiveListener).setNegativeButton( 
  7.                         "No", negativeListener).create().show(); 

`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、付费专栏及课程。

余额充值