我最初的目标是建立自己的模态对话框。在某些时候,我必须运行一个内部循环,这将非常接近Win32中的GetMessage / PostMessage,如果你有Win32经验,那么你对此非常熟悉。 内部循环将阻止当前工作流但仍处理事件。伪代码就像,
private void doModal() {
doSth();
// start loop and process events
while (!isQuit) {
Message msg = nextMessage();
// process all wanted msgs, and simply discard all unexpected msgs
if (isWantedMsg) {
sendToTarget(msg);
}
}
}
我查看了源代码,Looper.loop(),这是
public static final void loop() {
Looper me = myLooper();
MessageQueue queue = me.mQueue;
while (true) {
Message msg = queue.next(); // might block
if (msg != null) {
if (msg.target == null) {
// No target is a magic identifier for the quit message.
return;
}
msg.target.dispatchMessage(msg);
msg.recycle();
}
}
}
基本上我想写这样一个循环,然后我就能够接收所有的消息并处理或丢弃它们。不幸的是,MessageQueue属于android.os包,我没有权限访问它的大部分接口。 Activity.dispatchTouchEvent只是一个处理程序,而不是我的情况。
我该怎么办?感谢。
========================== SOLUTION ==================== =================
我通过反射解决了它,我完全复制了Looper.loop()的源代码,见下文,
private void startModal() {
Class clsMsgQueue = null;
Method nextMethod = null;
Class clsMsg = null;
mQuitModal = false;
MessageQueue queue = Looper.myQueue();
clsMsgQueue = queue.getClass();
try {
nextMethod = clsMsgQueue.getDeclaredMethod("next", new Class[]{});
} catch (SecurityException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (NoSuchMethodException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
nextMethod.setAccessible(true);
while (!mQuitModal) {
Message msg = null;
try {
msg = (Message)nextMethod.invoke(queue, new Object[]{});
} catch (IllegalArgumentException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalAccessException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InvocationTargetException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
if (msg != null) {
clsMsg = msg.getClass();
Field targetFiled = null;
try {
targetFiled = clsMsg.getDeclaredField("target");
} catch (SecurityException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (NoSuchFieldException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
targetFiled.setAccessible(true);
Handler target = null;
try {
target = (Handler) targetFiled.get(msg);
} catch (IllegalArgumentException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalAccessException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
if (target == null) {
// No target is a magic identifier for the quit message.
mQuitModal = true;
}
target.dispatchMessage(msg);
msg.recycle();
}
}
}
当对话框被解除时,mQuitModal也设置为true。
如果不关心性能问题,那就有用了。
答案 0 :(得分:2)
抱歉,Android故意不支持这样的嵌套事件循环。您只需要以不同的方式构建代码 - 对于对话框,您通常会启动对话框,返回事件循环,并实现回调以处理来自它的结果。