Android: "BadTokenException: Unable to add window; is your activity running?" at showing dialog in PreferenceActivity
Solution 1
I had a very similar issue (which landed me here) and found a very simple fix for it. While my code is different, it should be easy to adapt. Here is my fix:
public void showBox() {
mActive = true;
if (! ((Activity) mContext).isFinishing()) {
mDialogBox.show();
}
}
So, in the sample code in the question, the fix would have been (at a guess):
@Override
public void onSharedPreferenceChanged(SharedPreferences preferences, String key) {
if (key.equals("checkTest")) {
if (! this.isFinishing()) {
showDialog(1);
}
}
if (key.equals("cancel")) {
dismissDialog(1);
}
}// onSPC
Solution 2
Maybe you didn't close or unregister something in your activity. In that case, try unregistering the broadcastreceiver on onDestroy.
Solution 3
This is usually caused by your app trying to display a dialog using a previously-finished Activity
as a context
. Then check that the activity is not closed by some other apps or other triggers before showing the dialog
if (!isFinishing()) {
//showdialog here
}
Solution 4
After introducing crash tracking to a project, I noticed this issue popping up quite frequently and found the same fix worked throughout the project to eliminate the crash:
- Never declare/instantiate Dialogs as local variables.
- Make all Dialogs instance variables of the Activity.
- Override onDestroy and call if(dialog != null) dialog.dismiss();
Example:
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();
}
}
It is misleading that the error message says "unable to add window" as I've found the error happens when you are leaving an Activity and the context that was passed to your Dialog is dead.
Solution 5
For me this solved the problem.. checking if the dialog is null or not showing and if yes then create again.
// create alert dialog
if (enableNetworkDialog == null || !enableNetworkDialog.isShowing())
enableNetworkDialog = alertDialogBuilder.create();
if (context instanceof AppCompatActivity && !((AppCompatActivity) context).isFinishing())
enableNetworkDialog.show();
Lama
Updated on September 23, 2020Comments
-
Lama almost 4 years
I'd like to ask for some help: In my app, I have only one activity, a
PreferenceActivity
(don't need other, it's just a simple background-sync app, so thePrefsActivity
is the Main/Launcher). After the user setup preferences, checks acheckBoxPreference
, and that starts (or stops) a service. At starting, a dialog shows. But here is the problem: if the user press back (leave the activity), start it again, and than tries to check thecheckBoxPref
., theprefsactivity
crashes. Dialog doesn't shows. I have no idea why, and how to fix it.This code is exactly same with that part, what gives me the problem:
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>
and the manifest:
<?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 error:
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}
After googleing a lot, I think, the wrong part is the
ProgressDialog dialog = new ProgressDialog(this);
. Causethis
changes. But changing it togetApplicationContext()
, orPrefsActivity.this
doesn't help, the problem is still there. Please, tell me why is this happening, and what could be the solution! Thank You! I'm stuck, and now I have no idea...