私はいくつかの助けを求めたいです:私のアプリでは、1つのアクティビティ、PreferenceActivity
のみがあります(他の必要はありません。単純なバックグラウンド同期アプリなので、PrefsActivity
はメイン/ランチャーです)。ユーザー設定の設定後、checkBoxPreference
を確認し、サービスを開始(または停止)します。開始時に、ダイアログが表示されます。しかし、ここに問題があります:ユーザーが戻る(アクティビティを終了する)場合、もう一度開始し、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}
_
たくさんのグーグルをした後、間違った部分はProgressDialog dialog = new ProgressDialog(this);
だと思います。 this
が変更されます。しかし、それをgetApplicationContext()
、または_PrefsActivity.this
_に変更しても効果はありません。問題はまだそこにあります。なぜこれが起こっているのか、そして何が解決策なのか教えてください!ありがとうございました!私は立ち往生していて、今はわからない...
私は非常によく似た問題を抱えており(これが私をここに導きました)、それに対する非常に簡単な修正を見つけました。私のコードは異なりますが、簡単に適応できるはずです。ここに私の修正があります:
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でbroadcastreceiverの登録を解除してみてください。
私にとってこれは問題を解決しました。ダイアログがnullか表示されていないかを確認し、はいなら再度作成します。
// create alert dialog
if (enableNetworkDialog == null || !enableNetworkDialog.isShowing())
enableNetworkDialog = alertDialogBuilder.create();
if (context instanceof AppCompatActivity && !((AppCompatActivity) context).isFinishing())
enableNetworkDialog.show();
プロジェクトにクラッシュトラッキングを導入した後、この問題が非常に頻繁に発生することに気付き、クラッシュを解消するためにプロジェクト全体で同じ修正が機能することがわかりました。
例:
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に渡されたコンテキストが無効になっていることがわかりました。
一番上の解決策は、クラッシュを防ぐだけです。私にとって問題は、アラートダイアログを表示するために間違ったcontext
を参照していたことでした。正しいcontext
を渡した後、問題は解決しました。
これは通常、アプリがコンテキストとして以前に終了したアクティビティを使用してダイアログを表示しようとしたために発生します。次に、ダイアログを表示する前に、アクティビティが他のアプリや他のトリガーによって閉じられていないことを確認します
if (!isFinishing()) {
//showdialog here
}