ダイアログウィンドウを開こうとしていますが、開こうとするたびに次の例外がスローされます。
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
変数から来ていますデバッガに正しく入力されているようです。
Context appContext = this.getApplicationContext();
の代わりに、あなたがいるアクティビティへのポインタ(おそらくthis
)を使うべきです。
私も今日これに噛まれました、厄介な部分はgetApplicationContext()
はdeveloper.Android.comからの逐語的です:(
アクティビティではないコンテキストを介してアプリケーションウィンドウ/ダイアログを表示することはできません。有効なアクティビティ参照を渡してみてください
GetApplicationContextのことについても説明します。
Androidサイトの文書はそれを使用するように言っています、しかしそれは働きません... grrrrr :-P
ただしてください:
dialog = new Dialog(this);
"this"通常あなたがダイアログを開始するアクティビティです。
AndroidドキュメントではgetApplicationContext()を使用することを推奨しています。
alertDialog.Builder、AlertDialog、またはDialogをインスタンス化している間は、現在のアクティビティを使用するのではなく機能しません。
例:
AlertDialog.Builder builder = new AlertDialog.Builder(this);
または
AlertDialog.Builder builder = new AlertDialog.Builder((Your Activity).this);
getApplicationContext()
の代わりに、単にActivityName.this
を使用してください。
私は私がこのような何か他のクラスを持っていたときに私は同様の問題を抱えていました:
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
としてオブジェクトを保持する必要がなかったので、愚かな愚かな間違い...
それをに変えるだけです
AlertDialog.Builder alert_Categoryitem =
new AlertDialog.Builder(YourActivity.this);
の代わりに
AlertDialog.Builder alert_Categoryitem =
new AlertDialog.Builder(getApplicationContext());
別の解決策は、ウィンドウタイプをシステムダイアログに設定することです。
dialog.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);
これには SYSTEM_ALERT_WINDOW
権限が必要です。
<uses-permission Android:name="Android.permission.SYSTEM_ALERT_WINDOW" />
ドキュメントが言うように:
非常に少数のアプリケーションがこの許可を使うべきです。これらのウィンドウは、ユーザーとのシステムレベルの対話を目的としています。
これは、アクティビティに添付されていないダイアログが必要な場合にのみ使用するべきソリューションです。
Dialougeの宣言にgetApplicationContext()
を使わないでください
常にthis
またはあなたのactivity.this
を使ってください
これは私のために働きました -
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
入れ子になったダイアログでは、この問題は非常に一般的です。
AlertDialog.Builder mDialogBuilder = new AlertDialog.Builder(MyActivity.this);
代わりにが使用されます
mDialogBuilder = new AlertDialog.Builder(getApplicationContext);
この代替手段.
またこれをすることができます
public class Example extends Activity {
final Context context = this;
final Dialog dialog = new Dialog(context);
}
これは私のために働いた!
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());
dialog
ウィンドウのタイプをにリセットしてみてください
WindowManager.LayoutParams.TYPE_SYSTEM_ALERT:
dialog.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);
パーミッションAndroid.permission.SYSTEM_ALERT_WINDOW
を使うことを忘れないでください
言われているように、あなたはダイアログのコンテキストとしてActivityを必要とします。静的コンテキストのために "YourActivity.this"を使用するか、またはセーフモードで動的コンテキストを使用する方法については here
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);
}