我最初的目标是建立我自己的模态对话框。在某些时候,我必须运行一个内部循环,如果你有Win32的经验,那么你会非常熟悉Win32中的GetMessage/PostMessage。 内部循环将阻止当前工作流程,但仍处理事件。的伪代码会是什么样子,Android:如何接管Activity的消息循环,如Win32中的GetMessage/PostMessage?
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只是一个处理程序,而不是我的情况。
我该怎么办?谢谢。
==========================解决方法=================== ==================
我通过反射解决它,我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。
如果不太关心性能问题,它就起作用了。
简而言之,没有专业的开发人员应该使用此代码。 – CommonsWare 2011-06-02 17:17:21
我正在为Android构建调试器,并且需要在UI线程(用于断点)上暂停时处理UI事件。这段代码正是我所需要的。但是,我应该指出,msg.recycle不起作用,您需要调用'recycleUnchecked'。 – irbull 2016-03-03 22:45:44