From 20108e2ed6d7fdc889d85702f7cbda906db141cf Mon Sep 17 00:00:00 2001 From: "Jiehua.Dai" Date: Wed, 12 May 2010 08:37:52 +0200 Subject: [PATCH] Fix window leak problems in settings. There were window leak in the settings application. These leak happens when an AlertDialog displays, rotate the phone, then it would cause window leak. Change-Id: I914897bf657933efea72eeea66076dc288098420 --- src/com/android/settings/ApnEditor.java | 71 ++++++++++++++----- .../android/settings/LanguageSettings.java | 63 ++++++++++------ src/com/android/settings/ProxySelector.java | 35 +++++++-- .../settings/SettingsSafetyLegalActivity.java | 35 ++++++--- .../bluetooth/CachedBluetoothDevice.java | 31 ++++++-- src/com/android/settings/vpn/VpnEditor.java | 52 +++++++++----- 6 files changed, 208 insertions(+), 79 deletions(-) diff --git a/src/com/android/settings/ApnEditor.java b/src/com/android/settings/ApnEditor.java index e097854ee92..72dba1ab4dd 100644 --- a/src/com/android/settings/ApnEditor.java +++ b/src/com/android/settings/ApnEditor.java @@ -17,6 +17,7 @@ package com.android.settings; import android.app.AlertDialog; +import android.app.Dialog; import android.content.ContentUris; import android.content.ContentValues; import android.content.Intent; @@ -51,6 +52,7 @@ public class ApnEditor extends PreferenceActivity private static final int MENU_DELETE = Menu.FIRST; private static final int MENU_SAVE = Menu.FIRST + 1; private static final int MENU_CANCEL = Menu.FIRST + 2; + private static final int ERROR_DIALOG_ID = 0; private static String sNotSet; private EditTextPreference mName; @@ -347,19 +349,8 @@ public class ApnEditor extends PreferenceActivity String mcc = checkNotSet(mMcc.getText()); String mnc = checkNotSet(mMnc.getText()); - String errorMsg = null; - if (name.length() < 1) { - errorMsg = mRes.getString(R.string.error_name_empty); - } else if (apn.length() < 1) { - errorMsg = mRes.getString(R.string.error_apn_empty); - } else if (mcc.length() != 3) { - errorMsg = mRes.getString(R.string.error_mcc_not3); - } else if ((mnc.length() & 0xFFFE) != 2) { - errorMsg = mRes.getString(R.string.error_mnc_not23); - } - - if (errorMsg != null && !force) { - showErrorMessage(errorMsg); + if (getErrorMsg() != null && !force) { + showDialog(ERROR_DIALOG_ID); return false; } @@ -414,12 +405,54 @@ public class ApnEditor extends PreferenceActivity return true; } - private void showErrorMessage(String message) { - new AlertDialog.Builder(this) - .setTitle(R.string.error_title) - .setMessage(message) - .setPositiveButton(android.R.string.ok, null) - .show(); + private String getErrorMsg() { + String errorMsg = null; + + String name = checkNotSet(mName.getText()); + String apn = checkNotSet(mApn.getText()); + String mcc = checkNotSet(mMcc.getText()); + String mnc = checkNotSet(mMnc.getText()); + + if (name.length() < 1) { + errorMsg = mRes.getString(R.string.error_name_empty); + } else if (apn.length() < 1) { + errorMsg = mRes.getString(R.string.error_apn_empty); + } else if (mcc.length() != 3) { + errorMsg = mRes.getString(R.string.error_mcc_not3); + } else if ((mnc.length() & 0xFFFE) != 2) { + errorMsg = mRes.getString(R.string.error_mnc_not23); + } + + return errorMsg; + } + + @Override + protected Dialog onCreateDialog(int id) { + + if (id == ERROR_DIALOG_ID) { + String msg = getErrorMsg(); + + return new AlertDialog.Builder(this) + .setTitle(R.string.error_title) + .setPositiveButton(android.R.string.ok, null) + .setMessage(msg) + .create(); + } + + return super.onCreateDialog(id); + } + + @Override + protected void onPrepareDialog(int id, Dialog dialog) { + super.onPrepareDialog(id, dialog); + + if (id == ERROR_DIALOG_ID) { + String msg = getErrorMsg(); + + if (msg != null) { + ((AlertDialog)dialog).setMessage(msg); + } + } } private void deleteApn() { diff --git a/src/com/android/settings/LanguageSettings.java b/src/com/android/settings/LanguageSettings.java index 91d260cd092..1252eec26b0 100644 --- a/src/com/android/settings/LanguageSettings.java +++ b/src/com/android/settings/LanguageSettings.java @@ -55,6 +55,8 @@ public class LanguageSettings extends PreferenceActivity { private String mLastInputMethodId; private String mLastTickedInputMethodId; + + private AlertDialog mDialog = null; static public String getInputMethodIdFromKey(String key) { return key; @@ -255,29 +257,35 @@ public class LanguageSettings extends PreferenceActivity { if (selImi == null) { return super.onPreferenceTreeClick(preferenceScreen, preference); } - AlertDialog d = (new AlertDialog.Builder(this)) - .setTitle(android.R.string.dialog_alert_title) - .setIcon(android.R.drawable.ic_dialog_alert) - .setMessage(getString(R.string.ime_security_warning, - selImi.getServiceInfo().applicationInfo.loadLabel( - getPackageManager()))) - .setCancelable(true) - .setPositiveButton(android.R.string.ok, - new DialogInterface.OnClickListener() { - public void onClick(DialogInterface dialog, int which) { - chkPref.setChecked(true); - mLastTickedInputMethodId = id; - } - - }) - .setNegativeButton(android.R.string.cancel, - new DialogInterface.OnClickListener() { - public void onClick(DialogInterface dialog, int which) { - } - - }) - .create(); - d.show(); + if (mDialog == null) { + mDialog = (new AlertDialog.Builder(this)) + .setTitle(android.R.string.dialog_alert_title) + .setIcon(android.R.drawable.ic_dialog_alert) + .setCancelable(true) + .setPositiveButton(android.R.string.ok, + new DialogInterface.OnClickListener() { + public void onClick(DialogInterface dialog, int which) { + chkPref.setChecked(true); + mLastTickedInputMethodId = id; + } + + }) + .setNegativeButton(android.R.string.cancel, + new DialogInterface.OnClickListener() { + public void onClick(DialogInterface dialog, int which) { + } + + }) + .create(); + } else { + if (mDialog.isShowing()) { + mDialog.dismiss(); + } + } + mDialog.setMessage(getString(R.string.ime_security_warning, + selImi.getServiceInfo().applicationInfo.loadLabel( + getPackageManager()))); + mDialog.show(); } else if (id.equals(mLastTickedInputMethodId)) { mLastTickedInputMethodId = null; } @@ -302,4 +310,13 @@ public class LanguageSettings extends PreferenceActivity { return super.onPreferenceTreeClick(preferenceScreen, preference); } + @Override + protected void onDestroy() { + super.onDestroy(); + if (mDialog != null) { + mDialog.dismiss(); + mDialog = null; + } + } + } diff --git a/src/com/android/settings/ProxySelector.java b/src/com/android/settings/ProxySelector.java index 80fe3c90c98..66c81c62212 100644 --- a/src/com/android/settings/ProxySelector.java +++ b/src/com/android/settings/ProxySelector.java @@ -18,6 +18,7 @@ package com.android.settings; import android.app.Activity; import android.app.AlertDialog; +import android.app.Dialog; import android.content.ContentResolver; import android.content.Intent; import android.net.Proxy; @@ -73,6 +74,7 @@ public class ProxySelector extends Activity HOSTNAME_PATTERN = Pattern.compile(HOSTNAME_REGEXP); } + private static final int ERROR_DIALOG_ID = 0; public void onCreate(Bundle icicle) { super.onCreate(icicle); @@ -84,13 +86,32 @@ public class ProxySelector extends Activity populateFields(false); } - protected void showError(int error) { + @Override + protected Dialog onCreateDialog(int id) { + if (id == ERROR_DIALOG_ID) { + String hostname = mHostnameField.getText().toString().trim(); + String portStr = mPortField.getText().toString().trim(); + String msg = getString(validate(hostname, portStr)); - new AlertDialog.Builder(this) - .setTitle(R.string.proxy_error) - .setMessage(error) - .setPositiveButton(R.string.proxy_error_dismiss, null) - .show(); + return new AlertDialog.Builder(this) + .setTitle(R.string.proxy_error) + .setPositiveButton(R.string.proxy_error_dismiss, null) + .setMessage(msg) + .create(); + } + return super.onCreateDialog(id); + } + + @Override + protected void onPrepareDialog(int id, Dialog dialog) { + super.onPrepareDialog(id, dialog); + + if (id == ERROR_DIALOG_ID) { + String hostname = mHostnameField.getText().toString().trim(); + String portStr = mPortField.getText().toString().trim(); + String msg = getString(validate(hostname, portStr)); + ((AlertDialog)dialog).setMessage(msg); + } } void initView() { @@ -188,7 +209,7 @@ public class ProxySelector extends Activity int result = validate(hostname, portStr); if (result > 0) { - showError(result); + showDialog(ERROR_DIALOG_ID); return false; } diff --git a/src/com/android/settings/SettingsSafetyLegalActivity.java b/src/com/android/settings/SettingsSafetyLegalActivity.java index 0c51928bc15..368ee1dd68c 100644 --- a/src/com/android/settings/SettingsSafetyLegalActivity.java +++ b/src/com/android/settings/SettingsSafetyLegalActivity.java @@ -40,6 +40,8 @@ public class SettingsSafetyLegalActivity extends AlertActivity private WebView mWebView; + private AlertDialog mErrorDialog = null; + @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); @@ -85,14 +87,31 @@ public class SettingsSafetyLegalActivity extends AlertActivity } private void showErrorAndFinish(String url) { - new AlertDialog.Builder(this) - .setMessage(getResources() - .getString(R.string.settings_safetylegal_activity_unreachable, url)) - .setTitle(R.string.settings_safetylegal_activity_title) - .setPositiveButton(android.R.string.ok, this) - .setOnCancelListener(this) - .setCancelable(true) - .show(); + if (mErrorDialog == null) { + mErrorDialog = new AlertDialog.Builder(this) + .setTitle(R.string.settings_safetylegal_activity_title) + .setPositiveButton(android.R.string.ok, this) + .setOnCancelListener(this) + .setCancelable(true) + .create(); + } else { + if (mErrorDialog.isShowing()) { + mErrorDialog.dismiss(); + } + } + mErrorDialog.setMessage(getResources() + .getString(R.string.settings_safetylegal_activity_unreachable, url)); + mErrorDialog.show(); + } + + @Override + protected void onDestroy() { + super.onDestroy(); + + if (mErrorDialog != null) { + mErrorDialog.dismiss(); + mErrorDialog = null; + } } @Override diff --git a/src/com/android/settings/bluetooth/CachedBluetoothDevice.java b/src/com/android/settings/bluetooth/CachedBluetoothDevice.java index aa4a9584176..253bf0297a2 100644 --- a/src/com/android/settings/bluetooth/CachedBluetoothDevice.java +++ b/src/com/android/settings/bluetooth/CachedBluetoothDevice.java @@ -71,6 +71,8 @@ public class CachedBluetoothDevice implements Comparable private final LocalBluetoothManager mLocalManager; + private AlertDialog mDialog = null; + private List mCallbacks = new ArrayList(); /** @@ -375,12 +377,29 @@ public class CachedBluetoothDevice implements Comparable } }; - new AlertDialog.Builder(context) - .setTitle(getName()) - .setMessage(message) - .setPositiveButton(android.R.string.ok, disconnectListener) - .setNegativeButton(android.R.string.cancel, null) - .show(); + if (mDialog == null) { + mDialog = new AlertDialog.Builder(context) + .setPositiveButton(android.R.string.ok, disconnectListener) + .setNegativeButton(android.R.string.cancel, null) + .create(); + } else { + if (mDialog.isShowing()) { + mDialog.dismiss(); + } + } + mDialog.setTitle(getName()); + mDialog.setMessage(message); + mDialog.show(); + } + + @Override + protected void finalize() throws Throwable { + if (mDialog != null) { + mDialog.dismiss(); + mDialog = null; + } + + super.finalize(); } public void connect() { diff --git a/src/com/android/settings/vpn/VpnEditor.java b/src/com/android/settings/vpn/VpnEditor.java index 497f4bfa42b..349befbf144 100644 --- a/src/com/android/settings/vpn/VpnEditor.java +++ b/src/com/android/settings/vpn/VpnEditor.java @@ -19,6 +19,7 @@ package com.android.settings.vpn; import com.android.settings.R; import android.app.AlertDialog; +import android.app.Dialog; import android.content.DialogInterface; import android.content.Intent; import android.net.vpn.L2tpIpsecProfile; @@ -44,6 +45,7 @@ import android.view.View; public class VpnEditor extends PreferenceActivity { private static final int MENU_SAVE = Menu.FIRST; private static final int MENU_CANCEL = Menu.FIRST + 1; + private static final int CONFIRM_DIALOG_ID = 0; private static final String KEY_PROFILE = "profile"; private static final String KEY_ORIGINAL_PROFILE_NAME = "orig_profile_name"; @@ -98,7 +100,7 @@ public class VpnEditor extends PreferenceActivity { case MENU_CANCEL: if (profileChanged()) { - showCancellationConfirmDialog(); + showDialog(CONFIRM_DIALOG_ID); } else { finish(); } @@ -171,21 +173,39 @@ public class VpnEditor extends PreferenceActivity { } } - private void showCancellationConfirmDialog() { - new AlertDialog.Builder(this) - .setTitle(android.R.string.dialog_alert_title) - .setIcon(android.R.drawable.ic_dialog_alert) - .setMessage(mAddingProfile - ? R.string.vpn_confirm_add_profile_cancellation - : R.string.vpn_confirm_edit_profile_cancellation) - .setPositiveButton(R.string.vpn_yes_button, - new DialogInterface.OnClickListener() { - public void onClick(DialogInterface dialog, int w) { - finish(); - } - }) - .setNegativeButton(R.string.vpn_mistake_button, null) - .show(); + + @Override + protected Dialog onCreateDialog(int id) { + + if (id == CONFIRM_DIALOG_ID) { + return new AlertDialog.Builder(this) + .setTitle(android.R.string.dialog_alert_title) + .setIcon(android.R.drawable.ic_dialog_alert) + .setMessage(mAddingProfile + ? R.string.vpn_confirm_add_profile_cancellation + : R.string.vpn_confirm_edit_profile_cancellation) + .setPositiveButton(R.string.vpn_yes_button, + new DialogInterface.OnClickListener() { + public void onClick(DialogInterface dialog, int w) { + finish(); + } + }) + .setNegativeButton(R.string.vpn_mistake_button, null) + .create(); + } + + return super.onCreateDialog(id); + } + + @Override + protected void onPrepareDialog(int id, Dialog dialog) { + super.onPrepareDialog(id, dialog); + + if (id == CONFIRM_DIALOG_ID) { + ((AlertDialog)dialog).setMessage(mAddingProfile + ? getString(R.string.vpn_confirm_add_profile_cancellation) + : getString(R.string.vpn_confirm_edit_profile_cancellation)); + } } private VpnProfile getProfile() {