在博客《AlertDialog创建过程详解》这篇博客中详细的说了Alert的创建过程,本篇博文就对Dialog的使用的知识点做其他的补充,闲言少叙,书归正传。
我们在关闭Dialog的时候是调用dismiss方法来关闭的,这个方法是线程安全的,通过该方法的实现上也可以体现出来:
private final Handler mHandler = new Handler();
private final Runnable mDismissAction = new Runnable() {
public void run() {
dismissDialog();
}
};
public void dismiss() {
//如果不是在UI线程中
if (Thread.currentThread() != mUiThread) {
mHandler.post(mDismissAction);
} else {
mDismissAction.run();
}
}
Dialog(Context context, int theme, boolean createContextWrapper) {
//获取当前线程,也就是uiThrad
mUiThread = Thread.currentThread();
//处理Dialog show canncel dismiss的Handler
mListenersHandler = new ListenersHandler(this);
}
如果是非UI线程就通过Handler的post方法将mDismissAction这个Runnable传到Handler内部Looper去处理,如果是在UI线程中那么直接调用mDismissAction这个Ruannable对象的run方法(此时mDismissAction就是一个很普通的Java对象),效果跟是直接调用dismissDialog一样。
所以在我们在使用Dialog或者AlertDialog调用dismiss关闭Dialog的时候,下面的两种方式都是可以的,使用哪一个就看你自己的业务逻辑了:
new Thread() {
public void run() {
dialog.dismiss();
}
}.start();
或者
dialog.dismiss()//此时位于UI线程中
在关闭DiaoLog的时候,是调用dismissDialog这个方法来处理的:
private void dismissDialog() {
if (mDecor == null || !mShowing) {
return;
}
//实际上是从mWindowManager中删除这个mDecor
try {
mWindowManager.removeView(mDecor);
} finally {
mDecor = null;
mWindow.closeAllPanels();
onStop();
mShowing = false;
//发送一个消息,在关闭Dialog的时候可以让用户做一些其他的操作。
sendDismissMessage();
}
}
实际上关闭Dialog的核心原理很简单,跟关闭PopupWindow的原理一样(详见《 关于PopupWindow的简单说明》);事实上如果读者留心注意的话,会发现android实现的悬浮框等只要是有WindowManager的地方,关闭窗口的操作实际上调用的就是WindowManager的removeView操作(关于WidnowManager,详见《 WIndowMangaer杂谈》);
在《AlertDialog创建过程详解》总我们知道在调用show方法显示出来Dialog界面的时候调用sendShowMessage(); 方法发送一个消息;而关闭Dialog的时候又调用sendDismissMessage();发用了一个关闭界面的消息,正因为这两个消息的存在所以我们可以在Dialog刚显示或者关闭的时候做一些额外的操作,在代码中的体现如下:
//Dialog显示的时候调用,该方法内部会初始化Dialog的mShowMessage 这个变量,稍后会说明
dialog.setOnShowListener(new OnShowListener() {
@Override
public void onShow(DialogInterface dialog) {
Log.e("DialogTest","show Dialog,when the dialog is visialble,you can invoke this method to do something");
}
});
//Dialog关闭的时候调用
dialog.setOnDismissListener(new OnDismissListener() {
@Override
public void onDismiss(DialogInterface dialog) {
Log.e("DialogTest","close Dialog,when you dimiss the dialog ,you can invoke this method to do something");
}
});
关于这两个方法具体怎么回调的,下面只挑
sendShowMessage方法来说明,sendDismissMessage方法的处理跟sendShowMessage方法类似就不在赘述。
private void sendShowMessage() {
if (mShowMessage != null) {
Message.obtain(mShowMessage).sendToTarget();
}
}
mShowMessage 这个Message类型的变量在你调用setOnShowListener的时候做了初始化:
public void setOnShowListener(OnShowListener listener) {
if (listener != null) {
mShowMessage = mListenersHandler.obtainMessage(SHOW, listener);
} else {
mShowMessage = null;
}
}
private static final class ListenersHandler extends Handler {
private WeakReference mDialog;
public ListenersHandler(Dialog dialog) {
mDialog = new WeakReference(dialog);
}
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
//此处省略了DIMISS,CANCLE两个case支线
case SHOW:
((OnShowListener) msg.obj).onShow(mDialog.get());
break;
}
}
}
在看到这个方法之前,你可能会想到这个方法的内部的逻辑。很简单,就是简单的回调调用了你在程序中设置的OnShowListener的onShow方法。该方法的参数从该handler的初始化中可以看出来,指的是Dialog本身。
本篇博文就先到此位置吧,以后遇到Dialog的其余知识点还会补充,发现自己写博客的时候总喜欢引用一下自己以前写的博客链接,不知道是好是坏,但是有一点可以肯定的是android的知识点看起来很碎很凌乱,但是大体上的脉络还是很清晰的,借助查阅资料和查看源码,一点点积累总能不断的收获。