Android: «BadTokenException: невозможно добавить окно; Ваша активность работает? »При отображении диалога в PreferenceActivity

Я хотел бы попросить некоторую помощь: в моем приложении у меня есть только одно действие: PreferenceActivity (не нужно другое, это просто приложение для синхронизации фона, поэтому PrefsActivity является основным / Launcher). После настроек настройки пользователя проверяет checkBoxPreference и запускает (или останавливает) службу. При запуске открывается диалоговое окно. Но вот проблема: если пользователь checkBoxPref на prefsactivity (оставьте действие), запустите его снова, а затем попытается проверить checkBoxPref ., prefsactivity падает. Диалог не отображается. Я понятия не имею, почему и как это исправить.

Этот код точно такой же с той частью, что дает мне проблему:

PrefsActivity.java:

  package is.it.works; // imports ..... public class PrefsActivity extends PreferenceActivity implements OnSharedPreferenceChangeListener { SharedPreferences prefs; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); addPreferencesFromResource(R.xml.prefs); prefs = PreferenceManager.getDefaultSharedPreferences(this); prefs.registerOnSharedPreferenceChangeListener(this); }// onCreate @Override public void onSharedPreferenceChanged(SharedPreferences preferences, String key) { if (key.equals("checkTest")) { showDialog(1); } if (key.equals("cancel")) { dismissDialog(1); } }// onSPC @Override protected Dialog onCreateDialog(int id) { switch (id) { case 1: { ProgressDialog dialog = new ProgressDialog(this); dialog.setMessage("press back twice, start the app again, and click checkbox..."); dialog.setIndeterminate(true); dialog.setCancelable(true); dialog.setOnCancelListener(new OnCancelListener() { @Override public void onCancel(DialogInterface dialog) { prefs.edit().putBoolean("cancel", false).commit(); } }); return dialog; }// case }// switch return null; }// onCreateDialog }// PrefsActivity 

prefs.xml:

 <?xml version="1.0" encoding="utf-8"?> <PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"> <CheckBoxPreference android:key="checkTest" android:title="test" /> </PreferenceScreen> 

И манифест:

 <?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="is.it.works" android:versionCode="1" android:versionName="1.0"> <uses-sdk android:minSdkVersion="4" /> <application android:icon="@drawable/icon" android:label="@string/app_name"> <activity android:name=".PrefsActivity" android:label="@string/app_name"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> </application> </manifest> 

Ошибка LogCat:

 09-14 10:34:34.472: ERROR/AndroidRuntime(281): Uncaught handler: thread main exiting due to uncaught exception 09-14 10:34:34.502: ERROR/AndroidRuntime(281): android.view.WindowManager$BadTokenException: Unable to add window -- token android.os.BinderProxy@43756de8 is not valid; is your activity running? 09-14 10:34:34.502: ERROR/AndroidRuntime(281): at android.view.ViewRoot.setView(ViewRoot.java:456) 09-14 10:34:34.502: ERROR/AndroidRuntime(281): at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:177) 09-14 10:34:34.502: ERROR/AndroidRuntime(281): at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:91) 09-14 10:34:34.502: ERROR/AndroidRuntime(281): at android.view.Window$LocalWindowManager.addView(Window.java:409) 09-14 10:34:34.502: ERROR/AndroidRuntime(281): at android.app.Dialog.show(Dialog.java:238) 09-14 10:34:34.502: ERROR/AndroidRuntime(281): at android.app.Activity.showDialog(Activity.java:2413) 09-14 10:34:34.502: ERROR/AndroidRuntime(281): at is.it.works.PrefsActivity.onSharedPreferenceChanged(PrefsActivity.java:27) 09-14 10:34:34.502: ERROR/AndroidRuntime(281): at android.app.ApplicationContext$SharedPreferencesImpl$EditorImpl.commit(ApplicationContext.java:2727) 09-14 10:34:34.502: ERROR/AndroidRuntime(281): at android.preference.Preference.tryCommit(Preference.java:1199) 09-14 10:34:34.502: ERROR/AndroidRuntime(281): at android.preference.Preference.persistBoolean(Preference.java:1404) 09-14 10:34:34.502: ERROR/AndroidRuntime(281): at android.preference.CheckBoxPreference.setChecked(CheckBoxPreference.java:155) 09-14 10:34:34.502: ERROR/AndroidRuntime(281): at android.preference.CheckBoxPreference.onClick(CheckBoxPreference.java:143) 09-14 10:34:34.502: ERROR/AndroidRuntime(281): at android.preference.Preference.performClick(Preference.java:811) 09-14 10:34:34.502: ERROR/AndroidRuntime(281): at android.preference.PreferenceScreen.onItemClick(PreferenceScreen.java:190) 09-14 10:34:34.502: ERROR/AndroidRuntime(281): at android.widget.AdapterView.performItemClick(AdapterView.java:284) 09-14 10:34:34.502: ERROR/AndroidRuntime(281): at android.widget.ListView.performItemClick(ListView.java:3246) 09-14 10:34:34.502: ERROR/AndroidRuntime(281): at android.widget.AbsListView$PerformClick.run(AbsListView.java:1635) 09-14 10:34:34.502: ERROR/AndroidRuntime(281): at android.os.Handler.handleCallback(Handler.java:587) 09-14 10:34:34.502: ERROR/AndroidRuntime(281): at android.os.Handler.dispatchMessage(Handler.java:92) 09-14 10:34:34.502: ERROR/AndroidRuntime(281): at android.os.Looper.loop(Looper.java:123) 09-14 10:34:34.502: ERROR/AndroidRuntime(281): at android.app.ActivityThread.main(ActivityThread.java:4203) 09-14 10:34:34.502: ERROR/AndroidRuntime(281): at java.lang.reflect.Method.invokeNative(Native Method) 09-14 10:34:34.502: ERROR/AndroidRuntime(281): at java.lang.reflect.Method.invoke(Method.java:521) 09-14 10:34:34.502: ERROR/AndroidRuntime(281): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:791) 09-14 10:34:34.502: ERROR/AndroidRuntime(281): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:549) 09-14 10:34:34.502: ERROR/AndroidRuntime(281): at dalvik.system.NativeStart.main(Native Method) 09-14 10:34:34.522: INFO/Process(52): Sending signal. PID: 281 SIG: 3 09-14 10:34:34.532: INFO/dalvikvm(281): threadid=7: reacting to signal 3 09-14 10:34:34.592: INFO/dalvikvm(281): Wrote stack trace to '/data/anr/traces.txt' 09-14 10:34:38.533: DEBUG/dalvikvm(107): GC freed 437 objects / 21560 bytes in 136ms 09-14 10:34:39.183: INFO/global(175): Default buffer size used in BufferedReader constructor. It would be better to be explicit if an 8k-char buffer is required. 09-14 10:34:44.632: INFO/global(175): Default buffer size used in BufferedReader constructor. It would be better to be explicit if an 8k-char buffer is required. 09-14 10:34:47.412: INFO/Process(281): Sending signal. PID: 281 SIG: 9 09-14 10:34:47.472: INFO/ActivityManager(52): Process is.it.works (pid 281) has died. 09-14 10:34:47.492: INFO/WindowManager(52): WIN DEATH: Window{4394f638 is.it.works/is.it.works.PrefsActivity paused=false} 

Я думаю, что после googleing, неправильной частью является ProgressDialog dialog = new ProgressDialog(this); , this изменится. Но изменив его на getApplicationContext() или PrefsActivity.this не помогает, проблема все еще существует. Пожалуйста, скажите мне, почему это происходит, и что может быть решением! Спасибо! Я застрял, и теперь я понятия не имею …

Solutions Collecting From Web of "Android: «BadTokenException: невозможно добавить окно; Ваша активность работает? »При отображении диалога в PreferenceActivity"

У меня был очень похожий вопрос (который приземлился на меня здесь) и нашел для него очень простое решение. Хотя мой код отличается, его легко адаптировать. Вот мое исправление:

 public void showBox() { mActive = true; if (! ((Activity) mContext).isFinishing()) { mDialogBox.show(); } } 

Итак, в примере кода в вопросе исправление было бы (по предположению):

 @Override public void onSharedPreferenceChanged(SharedPreferences preferences, String key) { if (key.equals("checkTest")) { if (! this.isFinishing()) { showDialog(1); } } if (key.equals("cancel")) { dismissDialog(1); } }// onSPC 

Возможно, вы не закрыли или не зарегистрировали что-то в своей деятельности. В этом случае попробуйте отменить регистрацию трансляции на onDestroy.

После внедрения отслеживания сбоев в проекте я заметил, что эта проблема возникала довольно часто и обнаружила, что такое же исправление работало во всем проекте, чтобы устранить крах:

  • Никогда не объявляйте / не создавайте диалоговые окна как локальные переменные.
  • Внесите все переменные экземпляра Dialogs из Activity.
  • Переопределить onDestroy и вызвать if (dialog! = Null) dialog.dismiss ();

Пример:

 MyActivity extends Activity { ProgressDialog mProgressDialog; AlertDialog mAlertDialog; @Override public void onCreate(Bundle savedInstanceState) { mProgressDialog = new ProgressDialog(MyActivity.this); mAlertDialog = new AlertDialog.Builder(MyActivity.this).show(); } @Override public void onDestroy() { super.onDestroy(); if(mProgressDialog != null) { mProgressDialog.dismiss(); } if(mAlertDialog != null) { mAlertDialog.dismiss(); } } 

Неверно, что сообщение об ошибке говорит «не удается добавить окно», поскольку я обнаружил, что ошибка возникает, когда вы покидаете Activity, и контекст, который был передан вашему диалогу, мертв.

Верхнее решение предотвращает только крах. Для меня проблема заключалась в том, что я указал неверный context для отображения диалогового окна предупреждения. После прохождения правильного context проблема была решена.