錯誤代碼分析
// 錯誤:方法返回 void,無法獲取 Dialog 實例
public void alertbox(String title, String message) {
new AlertDialog.Builder(this)
.setTitle(title)
.setMessage(message)
.setNeutralButton(android.R.string.cancel, null)
.show(); // 直接 show,無引用保留
}
// 外部調用
private void doCheck() {
alertbox("status", "checking...");
// ... 執行耗時操作 ...
alertbox.dismiss(); // 編譯錯誤:alertbox 是方法非對象
}
修正方案:返回 AlertDialog 實例
// 1. 修改方法簽名,返回 AlertDialog
public AlertDialog createAlertDialog(String title, String message) {
return new AlertDialog.Builder(this)
.setTitle(title)
.setMessage(message)
.setNeutralButton(android.R.string.cancel, null)
.create(); // 僅創建,不 show
}
// 2. 調用處持有引用,按需 show/dismiss
private AlertDialog checkingDialog;
private void doCheck() {
checkingDialog = createAlertDialog("狀態", "正在檢查授權...");
checkingDialog.show();
mChecker.checkAccess(callback); // 假設異步回調
// 若需同步關閉(如檢查極快),放在回調中
}
// 3. 回調中關閉
private LicenseCheckerCallback mLicenseCheckerCallback = new LicenseCheckerCallback() {
@Override
public void allow(int reason) {
if (checkingDialog != null && checkingDialog.isShowing()) {
checkingDialog.dismiss();
}
}
@Override
public void dontAllow(int reason) {
if (checkingDialog != null && checkingDialog.isShowing()) {
checkingDialog.dismiss();
}
showErrorDialog();
}
};
進階:封裝為工具類(單例/靜態方法)
public class DialogUtils {
public static AlertDialog showCheckingDialog(Context context, String msg, OnDismissListener listener) {
AlertDialog dialog = new AlertDialog.Builder(context)
.setMessage(msg)
.setCancelable(false)
.create();
dialog.setOnDismissListener(listener);
dialog.show();
return dialog;
}
}
// 使用
AlertDialog dialog = DialogUtils.showCheckingDialog(this, "檢查中...", d -> {
// 關閉後邏輯
});
// 異步任務完成後
dialog.dismiss();
關鍵原則
- 創建與顯示分離:
create() 返回對象,show() 顯示,調用者決定生命周期。
- 持有引用:成員變量或局部 final 變量保存
AlertDialog 實例。
- 防洩漏:
onDestroy() 中檢查 dialog != null && dialog.isShowing() 並 dismiss()。
- 異步場景:在回調/監聽器中關閉,而非同步代碼緊隨
show() 之後。