J'aimerais demander de l'aide: Dans mon application, je n'ai qu'une seule activité, une PreferenceActivity
(pas besoin d'autre, c'est juste une application de synchronisation d'arrière-plan simple, donc la PrefsActivity
est la fenêtre principale/lanceur. Une fois les préférences de configuration définies par l'utilisateur, vérifie une checkBoxPreference
et le démarrage (ou l'arrêt) d'un service. Au démarrage, une boîte de dialogue apparaît. Mais voici le problème: si l'utilisateur appuie en arrière (quitte l'activité), redémarrez-le et tente de vérifier la checkBoxPref
., La prefsactivity
plante. Le dialogue ne montre pas. Je ne sais pas pourquoi ni comment y remédier.
Ce code est exactement pareil avec cette partie, ce qui me pose le problème:
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>
et le manifeste:
<?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>
Erreur 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}
Après avoir beaucoup cherché sur Google, je pense que la mauvaise partie est le ProgressDialog dialog = new ProgressDialog(this);
. Cause this
changements. Mais le changer en getApplicationContext()
, ou PrefsActivity.this
ne résout pas le problème, le problème est toujours là… .. S'il vous plaît, dites-moi pourquoi cela se produit et quelle pourrait être la solution! Je vous remercie! Je suis coincé, et maintenant je n'ai aucune idée ...
J'ai eu un problème très similaire (qui m'a atterri ici) et a trouvé une solution très simple pour cela. Bien que mon code soit différent, il devrait être facile à adapter. Voici ma solution:
public void showBox() {
mActive = true;
if (! ((Activity) mContext).isFinishing()) {
mDialogBox.show();
}
}
Ainsi, dans l'exemple de code de la question, le correctif aurait été (à deviner):
@Override
public void onSharedPreferenceChanged(SharedPreferences preferences, String key) {
if (key.equals("checkTest")) {
if (! this.isFinishing()) {
showDialog(1);
}
}
if (key.equals("cancel")) {
dismissDialog(1);
}
}// onSPC
Peut-être que vous n'avez pas fermé ou annulé quelque chose dans votre activité. Dans ce cas, essayez de désenregistrer le broadcastcastreceiver de onDestroy.
Pour moi, cela a résolu le problème .. vérifier si le dialogue est nul ou ne s'affiche pas et si oui, créer à nouveau.
// create alert dialog
if (enableNetworkDialog == null || !enableNetworkDialog.isShowing())
enableNetworkDialog = alertDialogBuilder.create();
if (context instanceof AppCompatActivity && !((AppCompatActivity) context).isFinishing())
enableNetworkDialog.show();
Après avoir introduit le suivi des incidents dans un projet, j’ai remarqué que ce problème se posait assez souvent et que le même correctif fonctionnait tout au long du projet pour éliminer le blocage:
Exemple:
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();
}
}
Il est trompeur que le message d'erreur indique "impossible d'ajouter une fenêtre" car j'ai constaté que l'erreur se produit lorsque vous quittez une activité et que le contexte transmis à votre boîte de dialogue est mort.
La solution supérieure empêche uniquement le crash. Pour moi, le problème était que j'avais renvoyé une context
erronée pour afficher le dialogue d'alerte. Après avoir passé la context
correcte, le problème a été résolu.
Cela est généralement dû au fait que votre application tente d'afficher une boîte de dialogue en utilisant une activité déjà terminée comme contexte. Ensuite, vérifiez que l'activité n'est pas fermée par d'autres applications ou d'autres déclencheurs avant d'afficher la boîte de dialogue.
if (!isFinishing()) {
//showdialog here
}