点击AlertDialog的Positive Button后的处理流程


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();
}
};

可以看到,首先发送了mButtonPositiveMessage消息给Handler,
然后又向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();
}
}
}

对于MSG_DISMISS_DIALOG消息,则调用dismiss(),dialog被移出。
而对于DialogInterface.BUTTON_POSITIVE消息,则从msg中取出obj,
该msg对应于mButtonHandler中的mButtonPositiveMessage,
mButtonPositiveMessage是在setButton()时被赋值的:
mHandler.obtainMessage(whichButton, listener);

可以看到,用户传入的onClick listener被包装进了message中,在handler处理时,
又从message中取出来调用。

整个流程至此完全清晰。