306

ダイアログウィンドウを開こうとしていますが、開こうとするたびに次の例外がスローされます。

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)

showDialogディスプレイのIDで呼び出して作成しています。ハンドラーは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変数はデバッガーに正しく入力されているようです。

4

16 に答える 16

610

の代わりに: Context appContext = this.getApplicationContext(); 現在のアクティビティへのポインタを使用する必要があります(おそらくthis)。

私も今日これに噛まれました、厄介な部分はgetApplicationContext()developer.android.comからの逐語的です:(

于 2010-04-14T17:18:30.553 に答える
78

アクティビティではないコンテキストを介してアプリケーションウィンドウ/ダイアログを表示することはできません。有効なアクティビティ参照を渡してみてください

于 2010-04-14T06:44:12.277 に答える
45

getApplicationContextについても同様です。

アンドロイドサイトのドキュメントはそれを使用するように言っていますが、それは機能しません... grrrrr :-P

ただ行う:

dialog = new Dialog(this); 

「これ」は通常、ダイアログを開始するアクティビティです。

于 2010-05-08T03:26:05.267 に答える
43

Androidドキュメントでは、getApplicationContext();の使用が提案されています。

ただし、AlertDialog.Builder、AlertDialog、またはDialogをインスタンス化するときに、現在のアクティビティを使用する代わりに機能しません。

元:

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

また

AlertDialog.Builder builder = new  AlertDialog.Builder((Your Activity).this);
于 2012-02-08T07:34:39.863 に答える
17

の代わりにgetApplicationContext()ActivityName.this

于 2015-04-23T10:53:27.427 に答える
13

次のような別のクラスがある場合にも、同様の問題が発生しました。

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、コードの2回目の実行では、オブジェクトの元のバージョンが保持されていたため、Activity存在しなくなった元のバージョンを参照していました。

愚かな愚かな間違い、特に私がstatic最初の場所のようにオブジェクトを保持する必要がなかったので...

于 2011-08-03T13:52:28.520 に答える
12

に変更するだけです

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

それ以外の

AlertDialog.Builder alert_Categoryitem = 
    new AlertDialog.Builder(getApplicationContext());
于 2013-05-08T05:49:31.133 に答える
9

別の解決策は、ウィンドウタイプをシステムダイアログに設定することです。

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

これにはSYSTEM_ALERT_WINDOW許可が必要です。

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

ドキュメントが言うように:

この権限を使用する必要があるアプリケーションはほとんどありません。これらのウィンドウは、ユーザーとのシステムレベルの対話を目的としています。

これは、アクティビティに関連付けられていないダイアログが必要な場合にのみ使用する必要があるソリューションです。

于 2015-07-13T16:02:15.483 に答える
4

getApplicationContext()対話の宣言には使用しないでください

常に使用するthisactivity.this

于 2015-03-04T11:35:35.720 に答える
2

ネストされたダイアログの場合、この問題は非常に一般的です。

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

の代わりに使用されます

mDialogBuilder = new AlertDialog.Builder(getApplicationContext);

この代替。

于 2014-08-25T17:18:44.307 に答える
2

これは私のために働いた-

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
于 2015-12-06T10:31:26.427 に答える
0

これもできます

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

これは私のために働いた!!

于 2013-09-07T10:53:32.290 に答える
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);
//                          }
        });
    }

ここにテキスト:-のコンテキストを
取得するためにこれを使用しますactivityprogressdialog

 progressdialog = new ProgressDialog(Splash.this);

またprogressdialog = new ProgressDialog(this);

BroadcastListener これを使用して、ではなくのアプリケーションコンテキストを取得しますprogressdialog

progressdialog = new ProgressDialog(getApplicationContext());
progressdialog = new ProgressDialog(getBaseContext());
于 2016-01-30T13:22:57.293 に答える
0

言われているように、ダイアログのコンテキストとしてアクティビティが必要です。静的コンテキストには「YourActivity.this」を使用するか、セーフモードで動的コンテキストを使用する方法についてはこちらを確認してください

于 2016-02-22T10:13:46.607 に答える
0

dialogウィンドウのタイプをにリセットしてみてください

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

許可を使用することを忘れないでくださいandroid.permission.SYSTEM_ALERT_WINDOW

于 2016-03-03T08:07:19.500 に答える
0

メモリリークの問題を回避するために、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);
    }
于 2017-02-23T08:09:30.617 に答える