android - unable to add window-- token null is not valid is your activity running




Android 1.6:“android.view.WindowManager $ BadTokenException:無法添加窗口-標記null不適用於應用程序” (11)

我試圖打開一個對話窗口,但每次我嘗試打開它時,都會拋出此異常:

Uncaught handler: thread main exiting due to uncaught exception
android.view.WindowManager$BadTokenException: 
     Unable to add window -- token null is not for an application
  at android.view.ViewRoot.setView(ViewRoot.java:460)
  at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:177)
  at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:91)
  at android.app.Dialog.show(Dialog.java:238)
  at android.app.Activity.showDialog(Activity.java:2413)

我通過用顯示器的ID調用showDialog創建它。 onCreateDialog處理程序記錄正常,我可以在沒有問題的情況下通過它,但是我附加了它,因為它似乎缺少一些東西:

@Override
public Dialog onCreateDialog(int id)
{
    Dialog dialog;
    Context appContext = this.getApplicationContext();
    switch(id)
    {
        case RENAME_DIALOG_ID:
            Log.i("Edit", "Creating rename dialog...");
            dialog = new Dialog(appContext);
            dialog.setContentView(R.layout.rename);
            dialog.setTitle("Rename " + noteName);
            break;
        default:
            dialog = null;
            break;
    }
    return dialog;      
}

有什麼缺失嗎? 從onCreate創建對話框時,有些問題曾經討論過這個問題,這是因為活動尚未創建,但這是來自菜單對象的調用,並且appContext變量看起來像是正確地填充在調試器。


Android文檔建議使用getApplicationContext();

但它不會工作,而不是使用您當前的活動,而實例化AlertDialog.Builder或AlertDialog或Dialog ...

例如:

AlertDialog.Builder builder = new  AlertDialog.Builder(this);

要么

AlertDialog.Builder builder = new  AlertDialog.Builder((Your Activity).this);

不要使用getApplicationContext()聲明dialouge

總是使用this或你的activity.this


另一種解決方案是將窗口類型設置為系統對話框:

dialog.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);

這需要SYSTEM_ALERT_WINDOW權限:

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

正如文件所說:

很少的應用程序應該使用此權限; 這些窗口用於與用戶進行系統級交互。

如果您需要未附加到活動的對話框,則應該只使用這種解決方案。


同上getApplicationContext的東西。

Android網站上的文檔說要使用它,但它不起作用... grrrrr :-P

做就是了:

dialog = new Dialog(this); 

“this”通常是您從其開始對話的活動。


在AsyncTask中顯示'ProgressDialog',避免內存洩漏問題的最好也是最安全的方法是使用帶有Looper.main()的'Handler'。

    private ProgressDialog tProgressDialog;

然後在'onCreate'

    tProgressDialog = new ProgressDialog(this);
    tProgressDialog.setMessage(getString(R.string.loading));
    tProgressDialog.setIndeterminate(true);

現在你完成了設置部分。 現在在AsyncTask中調用'showProgress()'和'hideProgress()'。

    private void showProgress(){
        new Handler(Looper.getMainLooper()){
            @Override
            public void handleMessage(Message msg) {
                tProgressDialog.show();
            }
        }.sendEmptyMessage(1);
    }

    private void hideProgress(){
        new Handler(Looper.getMainLooper()){
            @Override
            public void handleMessage(Message msg) {
                tProgressDialog.dismiss();
            }
        }.sendEmptyMessage(1);
    }

對於嵌套對話框,這個問題非常普遍,它在什麼時候工作

AlertDialog.Builder mDialogBuilder = new AlertDialog.Builder(MyActivity.this);

被用來代替

mDialogBuilder = new AlertDialog.Builder(getApplicationContext);

這個選擇。


我有一個類似的問題,我有另一個類如下所示:

public class Something {
  MyActivity myActivity;

  public Something(MyActivity myActivity) {
    this.myActivity=myActivity;
  }

  public void someMethod() {
   .
   .
   AlertDialog.Builder builder = new AlertDialog.Builder(myActivity);
   .
   AlertDialog alert = builder.create();
   alert.show();
  }
}

大部分時間都工作得很好,但有時候會碰到相同的錯誤。 然後我意識到在MyActivity我有......

public class MyActivity extends Activity {
  public static Something something;

  public void someMethod() {
    if (something==null) {
      something=new Something(this);
    }
  }
}

因為我將對象保持為static ,所以代碼的第二次運行仍然保留對象的原始版本,因此仍然指的是原來的“ Activity ,這種Activity不存在。

傻愚蠢的錯誤,尤其是因為我真的不需要首先將對象保持為static ...


把它改成

AlertDialog.Builder alert_Categoryitem = 
    new AlertDialog.Builder(YourActivity.this);

代替

AlertDialog.Builder alert_Categoryitem = 
    new AlertDialog.Builder(getApplicationContext());

而不是getApplicationContext() ,只需使用ActivityName.this


而不是: Context appContext = this.getApplicationContext(); 你應該使用一個指向你所在活動的指針(可能是this )。

今天我也受到了這個困擾,煩人的部分是getApplicationContext()是從developer.android.com逐字記錄:(


public class Splash extends Activity {

    Location location;
    LocationManager locationManager;
    LocationListener locationlistener;
    ImageView image_view;
    ublic static ProgressDialog progressdialog;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        // TODO Auto-generated method stub
        super.onCreate(savedInstanceState);
        setContentView(R.layout.splash);
        progressdialog = new ProgressDialog(Splash.this);
           image_view.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                // TODO Auto-generated method stub

                        locationManager.requestLocationUpdates("gps", 100000, 1, locationlistener);
                        Toast.makeText(getApplicationContext(), "Getting Location plz wait...", Toast.LENGTH_SHORT).show();

                            progressdialog.setMessage("getting Location");
                            progressdialog.show();
                            Intent intent = new Intent(Splash.this,Show_LatLng.class);
//                          }
        });
    }

在這打字:-
使用它獲取progressdialog activity上下文

 progressdialog = new ProgressDialog(Splash.this);

progressdialog = new ProgressDialog(this);

使用它來獲取BroadcastListener應用程序上下文而不是progressdialog

progressdialog = new ProgressDialog(getApplicationContext());
progressdialog = new ProgressDialog(getBaseContext());






android-windowmanager