在DialogFragment 的子類中,調用
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// 保存整個實例
setRetainInstance(true);
}
期望結果是 彈出dialog,在屏幕旋轉後,保持彈出狀態,
但是未彈出,原因是
Dialog
public void dismiss() {
if (Looper.myLooper() == mHandler.getLooper()) {
dismissDialog();
} else {
mHandler.post(mDismissAction);
}
}
void dismissDialog() {
...
sendDismissMessage();
...
}
// 使用handler調用onDismiss
private void sendDismissMessage() {
if (mDismissMessage != null) {
// Obtain a new message so this dialog can be re-used
Message.obtain(mDismissMessage).sendToTarget();
}
}
屏幕旋轉後,looper執行 ReLaunchActivity,在ReLaunchActivity中執行
fragment的onDestroyView(),而DialogFragment 中
@Override
public void onDestroyView() {
super.onDestroyView();
if (mDialog != null) {
// Set removed here because this dismissal is just to hide
// the dialog -- we don't want this to cause the fragment to
// actually be removed.
mViewDestroyed = true;
mDialog.dismiss();
mDialog = null;
}
}
執行了 mDialog.dismiss();mDialog向looper發送message,
當ReLaunchActivity執行完之後,fragment attath到acitivity中,然後Looper執行下一個msg,就執行到
DialogFragment 的onDismiss中,而在
DialogFragment 中,調用了 dismissInternal(true);
@Override
public void onDismiss(DialogInterface dialog) {
if (!mViewDestroyed) {
// Note: we need to use allowStateLoss, because the dialog
// dispatches this asynchronously so we can receive the call
// after the activity is paused. Worst case, when the user comes
// back to the activity they see the dialog again.
dismissInternal(true);
}
}
dismissInternal 又調用了remove,DialogFragment 又從activity中移除,所以,dialog不會保持彈出狀態
解決辦法:
重寫DialogFragment 的onDismiss方法
@Override
public void onDismiss(DialogInterface dialog) {
LegoLog.d("dialog onDismiss");
}
但是不建議這樣做,還是不要使用 setRetainInstance(true);的方式,因爲會導致內存泄漏