diff --git a/app/src/main/java/com/hippo/preference/DialogPreference.java b/app/src/main/java/com/hippo/preference/DialogPreference.java index 5b757bbcd..c4222cb86 100644 --- a/app/src/main/java/com/hippo/preference/DialogPreference.java +++ b/app/src/main/java/com/hippo/preference/DialogPreference.java @@ -27,6 +27,7 @@ import android.os.Build; import android.os.Bundle; import android.os.Parcelable; import android.preference.Preference; +import android.preference.PreferenceManager; import android.support.annotation.DrawableRes; import android.support.annotation.StringRes; import android.support.v4.content.ContextCompat; @@ -45,7 +46,8 @@ import com.hippo.ehviewer.R; * actual preference controls. */ public abstract class DialogPreference extends Preference implements - DialogInterface.OnClickListener, DialogInterface.OnDismissListener { + DialogInterface.OnClickListener, DialogInterface.OnDismissListener, + PreferenceManager.OnActivityDestroyListener { private static final String KEY_SUPER = "super"; private static final String KEY_IS_DIALOG_SHOWING = "is_dialog_showing"; @@ -272,6 +274,8 @@ public abstract class DialogPreference extends Preference implements onPrepareDialogBuilder(mBuilder); + PreferenceUtils.registerOnActivityDestroyListener(this, this); + // Create the dialog final AlertDialog dialog = mDialog = mBuilder.create(); if (state != null) { @@ -336,6 +340,8 @@ public abstract class DialogPreference extends Preference implements @Override public void onDismiss(DialogInterface dialog) { + PreferenceUtils.unregisterOnActivityDestroyListener(this, this); + mDialog = null; onDialogClosed(mWhichButtonClicked == DialogInterface.BUTTON_POSITIVE); } @@ -359,6 +365,15 @@ public abstract class DialogPreference extends Preference implements return mDialog; } + @Override + public void onActivityDestroy() { + if (mDialog == null || !mDialog.isShowing()) { + return; + } + + mDialog.dismiss(); + } + @Override protected Parcelable onSaveInstanceState() { final Parcelable superState = super.onSaveInstanceState(); diff --git a/app/src/main/java/com/hippo/preference/PreferenceUtils.java b/app/src/main/java/com/hippo/preference/PreferenceUtils.java new file mode 100644 index 000000000..8c359fdc7 --- /dev/null +++ b/app/src/main/java/com/hippo/preference/PreferenceUtils.java @@ -0,0 +1,99 @@ +/* + * Copyright 2016 Hippo Seven + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.hippo.preference; + +import android.preference.Preference; +import android.preference.PreferenceManager; + +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; + +public final class PreferenceUtils { + private PreferenceUtils() {} + + private static final Method mRegisterOnActivityDestroyListener; + private static final Method mUnregisterOnActivityDestroyListener; + + static { + Method method; + Class clazz = PreferenceManager.class; + + method = null; + try { + method = clazz.getDeclaredMethod("registerOnActivityDestroyListener", + PreferenceManager.OnActivityDestroyListener.class); + if (null != method) { + method.setAccessible(true); + } + } catch (NoSuchMethodException e) { + e.printStackTrace(); + } + mRegisterOnActivityDestroyListener = method; + + method = null; + try { + method = clazz.getDeclaredMethod("unregisterOnActivityDestroyListener", + PreferenceManager.OnActivityDestroyListener.class); + if (null != method) { + method.setAccessible(true); + } + } catch (NoSuchMethodException e) { + e.printStackTrace(); + } + mUnregisterOnActivityDestroyListener = method; + } + + @SuppressWarnings("TryWithIdenticalCatches") + public static void registerOnActivityDestroyListener(Preference preference, + PreferenceManager.OnActivityDestroyListener listener) { + if (null == mRegisterOnActivityDestroyListener || null == preference || null == listener) { + return; + } + PreferenceManager preferenceManager = preference.getPreferenceManager(); + if (null == preferenceManager) { + return; + } + + try { + mRegisterOnActivityDestroyListener.invoke(preferenceManager, listener); + } catch (IllegalAccessException e) { + e.printStackTrace(); + } catch (InvocationTargetException e) { + e.printStackTrace(); + } + } + + @SuppressWarnings("TryWithIdenticalCatches") + public static void unregisterOnActivityDestroyListener(Preference preference, + PreferenceManager.OnActivityDestroyListener listener) { + if (null == mUnregisterOnActivityDestroyListener || null == preference || null == listener) { + return; + } + PreferenceManager preferenceManager = preference.getPreferenceManager(); + if (null == preferenceManager) { + return; + } + + try { + mUnregisterOnActivityDestroyListener.invoke(preferenceManager, listener); + } catch (IllegalAccessException e) { + e.printStackTrace(); + } catch (InvocationTargetException e) { + e.printStackTrace(); + } + } +}