Android:“BadTokenException:无法添加窗口;您的活动是否正在运行?”在PreferenceActivity中显示对话框

时间:2011-09-14 10:43:20

标签: android progressdialog preferenceactivity

我想请求一些帮助:在我的应用中,我只有一个活动,PreferenceActivity(不需要其他活动,它只是一个简单的后台同步应用,所以{{1是主/启动器)。在用户设置首选项之后,检查PrefsActivity,然后启动(或停止)服务。在开始时,会出现一个对话框。 但问题出在这里:如果用户按下(离开活动),再次启动它,然后尝试检查checkBoxPreferencecheckBoxPref崩溃。对话框没有显示。我不知道为什么,以及如何解决它。

这段代码与那部分完全相同,是什么给我带来了问题:

PrefsActivity.java:

prefsactivity

的prefs.xml:

   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

和清单:

<?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>

LogCat错误:

<?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>

经过googleing,我认为,错误的部分是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} 。导致ProgressDialog dialog = new ProgressDialog(this);更改。但是将其更改为thisgetApplicationContext()并没有帮助,问题仍然存在。 请告诉我为什么会发生这种情况,可能是什么解决方案!谢谢! 我被卡住了,现在我不知道......

6 个答案:

答案 0 :(得分:81)

我有一个非常类似的问题(让我来到这里)并找到了一个非常简单的解决方案。虽然我的代码不同,但应该很容易适应。这是我的修复:

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

答案 1 :(得分:4)

也许您没有关闭或取消注册活动中的某些内容。在这种情况下,请尝试在onDestroy上取消注册broadcastreceiver。

答案 2 :(得分:1)

在将崩溃跟踪引入项目之后,我注意到这个问题经常出现,并且在整个项目中发现同样的修复工作以消除崩溃:

  • 永远不要将对话框声明/实例化为局部变量。
  • 制作活动的所有Dialogs实例变量。
  • 覆盖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();
    }
  }

错误消息显示“无法添加窗口”是误导性的,因为我发现当您离开活动时发生错误并且传递给您的Dialog的上下文已经死亡。

答案 3 :(得分:1)

对我来说,这解决了问题..检查对话框是否为空或不显示,如果是,则再次创建。

    // create alert dialog
    if (enableNetworkDialog == null || !enableNetworkDialog.isShowing())
        enableNetworkDialog = alertDialogBuilder.create();
    if (context instanceof AppCompatActivity && !((AppCompatActivity) context).isFinishing())
        enableNetworkDialog.show(); 

答案 4 :(得分:0)

顶级解决方案只能防止崩溃。对我来说问题是我提到了一个错误的context来显示警告对话框。传递正确的context后,问题就解决了。

答案 5 :(得分:0)

这通常是由于您的应用尝试使用先前完成的“活动”作为上下文来显示对话框。然后在显示对话框之前,检查活动是否被其他一些应用程序或其他触发器未关闭

if (!isFinishing()) {
    //showdialog here
    }