282

我試圖打開一個對話窗口,但每次我嘗試打開它時都會拋出這個例外:

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變量看起來好像它正確地填充在調試器。

回答

597

相反的: Context appContext = this.getApplicationContext(); 你應該使用一個指向你(可能this)是活動的。

我得到今天這個被咬過,惱人的部分是getApplicationContext()是逐字從developer.android.com :(

+2

它也被報告爲一個錯誤(雖然它不是當用戶發佈問題時):http://code.google.com/p/android/issues/detail?id=11199 – 2011-09-30 00:45:50

+61

只是以防萬一這有助於任何人 - 在對話框中使用myActivity.this作爲上下文。 – 2011-12-05 15:55:10

+13

這個問題和答案在2天內變成3歲。我仍然獲得聲望,所以我猜Google還沒有修復他們的文檔... – Torp 2013-04-12 17:50:36

75

您不能通過不是活動的上下文顯示應用程序窗口/對話框。嘗試通過有效的活動引用

+0

怎麼樣?我嘗試了'activity.this'和'activity.getBaseContext()'但沒有用。任何幫助? – Darpan 2014-10-15 11:44:36

+3

明白了。直接傳遞您的活動名稱。沒有'.this'。 – Darpan 2014-10-15 11:52:49

+0

Darpan,你確實解決了我的問題。 – Machado 2015-02-20 11:58:44

43

同上的getApplicationContext事情。

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

只要做到:

dialog = new Dialog(this); 

「這個」通常是您從其開始對話的活動。

12

我有一個類似的問題在那裏我有另一個類是這樣的:

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,它不存在。

傻愚蠢的錯誤,特別是因爲我真的沒有需要被保持該物體在首位static ......

39

Android的文件建議使用getApplicationContext();

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

例:

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

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

這大大幫助了我。我試圖在另一個對話框中創建一個對話框,並且只有「AlertDialog.Builder(this);」發生了一個錯誤。謝謝! – EHarpham 2012-10-20 12:16:15

+0

(ActivityName.this)在嘗試在onClick按鈕中創建對話框時特別有用 – RmK 2014-12-16 11:51:42

+0

我的問題是我在適配器內部的AlertDialog內建立ProgressDialog ...我無法讓它工作。 – santafebound 2017-07-06 19:22:41

12

只是把它變成

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

而不是

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

你也可以這樣做

public class Example extends Activity { 
    final Context context = this; 
    final Dialog dialog = new Dialog(context); 
} 

這對我有效!

2

對於嵌套的對話框這個問題是很常見的,當

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

使用的

mDialogBuilder = new AlertDialog.Builder(getApplicationContext); 

這種替代,而不是它的工作原理。

4

不要在聲明的臺詞

始終使用this或您的activity.this

16

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

+0

這是正確的答案。 – Oussaki 2015-05-04 22:59:28

+0

這是正確的答案。 – user3687895 2015-05-11 15:28:11

9

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

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

這需要SYSTEM_ALERT_WINDOW權限:

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

由於文檔說:

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

這是一個解決方案,只有在您需要一個未附加到活動的對話框時才應該使用。

+0

這是來自API級別26的現已棄用的標誌。因爲它允許開發人員使用系統窗口進行玩耍,這從用戶角度來看並不好。 – CopsOnRoad 2018-01-19 06:51:13

3

這個工作對我 -

new AlertDialog.Builder(MainActivity.this) 
     .setMessage(Html.fromHtml("<b><i><u>Spread Knowledge Unto The Last</u></i></b>")) 
     .setCancelable(false) 
     .setPositiveButton("Dismiss", 
       new DialogInterface.OnClickListener() { 
        public void onClick(DialogInterface dialog, int id) { 
        } 
       }).show(); 

使用

ActivityName.this 
0
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); 
//       } 
     }); 
    } 

文本的位置: -
使用這樣來activity上下文progressdialog

progressdialog = new ProgressDialog(Splash.this); 

progressdialog = new ProgressDialog(this);

使用這種用於獲取應用程序上下文BroadcastListener 不是progressdialog

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

,因爲它是說,你需要一個活動作爲背景的對話框中,使用「YourActivity.this」爲靜態上下文或檢查here如何使用在安全模式下

0

嘗試一個動態到dialog窗口的類型重置爲

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

不要忘記使用許可android.permission.SYSTEM_ALERT_WINDOW

0

最好和保險櫃在AsyncTask中顯示'ProgressDialog',避免內存泄漏問題的方法是在Looper.main()中使用'Handler'。

private ProgressDialog tProgressDialog; 

然後在 '的onCreate'

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

現在,您R中的設置部分完成。現在在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); 
    } 
相關問題