android中的AlertDialog创建时,允许指定positive button被点击时调用的onClick()回调函数,
如:
new AlertDialog.Builder(this)
.setTitle("Single choice")
.setPositiveButton("OK", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int whichButton) {
/ User clicked Yes so do some stuff /
}
})
.setNegativeButton("cancel", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int whichButton) {
/ User clicked No so do some stuff /
}
})
.show();
但是我们在回调函数中并没有将dialog给dismiss()掉,那么为什么dialog会消失?
可以想到的一种解释是,在AlertDialog收到onClick事件主动调用用户传入的回调函数,
返回后再执行一段dismiss的代码。
android的onCreate()、onDestroy()等机制都是这么实现的,因此onClick()当然
可以按照同样方法实现。
AlertDialog的具体实现位于深入AlertDialog.java、AlertController.java
这两个文件中,从代码可以看出,AlertDialog创建时,
设置positive button、negative button、neutral button的
onClickListener为mButtonHandler(AlertController.java>setupButtons()),
因此Button在被点击时,真正执行的并不是用户传入的那个onClickListener!
mButtonHandler的定义如下:
View.OnClickListener mButtonHandler = new View.OnClickListener() {
public void onClick(View v) {
Message m = null;
if (v == mButtonPositive && mButtonPositiveMessage != null) {
m = Message.obtain(mButtonPositiveMessage);
} else if (v == mButtonNegative && mButtonNegativeMessage != null) {
m = Message.obtain(mButtonNegativeMessage);
} else if (v == mButtonNeutral && mButtonNeutralMessage != null) {
m = Message.obtain(mButtonNeutralMessage);
}
if (m != null) {
m.sendToTarget();
}
// Post a message so we dismiss after the above handlers are executed
mHandler.obtainMessage(ButtonHandler.MSG_DISMISS_DIALOG, mDialogInterface)
.sendToTarget();
}
};
然后又向Handler发送了一个MSG_DISMISS_DIALOG的请求。
Handler的处理如下:
private static final class ButtonHandler extends Handler {
// Button clicks have Message.what as the BUTTON{1,2,3} constant
private static final int MSG_DISMISS_DIALOG = 1;
private WeakReference<DialogInterface> mDialog;
public ButtonHandler(DialogInterface dialog) {
mDialog = new WeakReference<DialogInterface>(dialog);
}
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
case DialogInterface.BUTTON_POSITIVE:
case DialogInterface.BUTTON_NEGATIVE:
case DialogInterface.BUTTON_NEUTRAL:
((DialogInterface.OnClickListener) msg.obj).onClick(mDialog.get(), msg.what);
break;
case MSG_DISMISS_DIALOG:
((DialogInterface) msg.obj).dismiss();
}
}
}
而对于DialogInterface.BUTTON_POSITIVE消息,则从msg中取出obj,
该msg对应于mButtonHandler中的mButtonPositiveMessage,
mButtonPositiveMessage是在setButton()时被赋值的:
mHandler.obtainMessage(whichButton, listener);
可以看到,用户传入的onClick listener被包装进了message中,在handler处理时,
又从message中取出来调用。
整个流程至此完全清晰。