在博客《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<DialogInterface> mDialog; public ListenersHandler(Dialog dialog) { mDialog = new WeakReference<DialogInterface>(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的知识点看起来很碎很凌乱,但是大体上的脉络还是很清晰的,借助查阅资料和查看源码,一点点积累总能不断的收获。