我最初的目標是建立我自己的模態對話框。在某些時候,我必須運行一個內部循環,如果你有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