开发过程中,经常涉及到Dialog,一般场景是在主线程show Dialog,异步线程后返回到主线程中dismiss,而有时候往往会在Dialog show或者 dismiss的时候抛出 Activity不活动异常或者不能在Activity onSaveInstanceState之后Action。
原理:
Dialog的特性依赖于Activity的生命周期,所以应该把Dialog的控制权交回给Activity,让它在最合适的时候处理Dialog,而我们只需要通知Activity如何处理Dialog即可。
在Activity onSaveInstanceState之后不能对Dialog做show和 dismiss操作,而是让它在onResume的时候处理了。
代码如下:这里以FragmentActivity和DialogFragment作演示,换成Activity和Dialog同样适用。
import java.util.ArrayList;
import java.util.List;
import android.os.Bundle;
import android.support.v4.app.DialogFragment;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.FragmentManager;
public class BaseActivity extends FragmentActivity {
private boolean dialogOk = true;;
private List<DialogAction> dialogActions;
@Override
protected void onCreate(Bundle arg0) {
super.onCreate(arg0);
dialogActions = new ArrayList<BaseActivity.DialogAction>();
}
@Override
protected void onResume() {
super.onResume();
dialogOk = true;
while (!dialogActions.isEmpty()) {
DialogAction action = dialogActions.remove(0);
action.todo();
}
}
@Override
public void onSaveInstanceState(Bundle outState) {
dialogOk = false;
super.onSaveInstanceState(outState);
}
public void dismissDialog(DialogFragment dialogFragment) {
if (dialogOk) {
dialogFragment.dismiss();
} else {
DialogDismiss dialogDismiss = new DialogDismiss(dialogFragment);
dialogActions.add(dialogDismiss);
}
}
public void showDialog(DialogFragment dialogFragment, String tag) {
if (dialogOk) {
dialogFragment.show(getSupportFragmentManager(), tag);
} else {
DialogShow dialogShow = new DialogShow(dialogFragment, getSupportFragmentManager(), tag);
dialogActions.add(dialogShow);
}
}
private static interface DialogAction {
public void todo();
}
private static class DialogDismiss implements DialogAction {
private DialogFragment dialogFragment;
private DialogDismiss(DialogFragment dialogFragment) {
this.dialogFragment = dialogFragment;
}
@Override
public void todo() {
dialogFragment.dismiss();
}
}
private static class DialogShow implements DialogAction {
private DialogFragment dialogFragment;
private FragmentManager manager;
private String tag;
public DialogShow(DialogFragment dialogFragment, FragmentManager manager, String tag) {
this.dialogFragment = dialogFragment;
this.manager = manager;
this.tag = tag;
}
@Override
public void todo() {
dialogFragment.show(manager, tag);
}
}
}