I have talk about Handler in an article before. http://blog.csdn.net/elfylin/article/details/6085042.
Here mainly i want to discuss something between Hander and Message.
1. Message has some frequently used members as below:
int what; message id
int arg1;
int arg2;
Object obj; //An arbitrary object to send to the recipient , useful when use Messenger to send message.
Bundle data;
Handler target;
int flags;
long when;
Runnable callback;
Messenger replyTo;
2 Message.sendToTarget()
Message has a function, sendToTarget
public void sendToTarget() { target.sendMessage(this); }
which will call it's target's sendMessage,
and then push the message to the target's Queue.
and final call the target's handleMessage(),
(it's target is a Handler.)
that is to say, Handler's handleMessage.
3. Message.obtain(Message msg);
newMessage = Message.obtain(oldMessage)
genereate a new message
the newmessage and the old one share the same parameters as below:
what, arg1, arg2, replyTo, data, target, callback.
4 .Message obtain(Handler h)
get a new message, the
message's target is h, and others are default (unset).
5. Message's otherobtain function
Message obtain(Handler h, int what, Object obj)
obtain(Handler h, int what, int arg1, int arg2)
... and so on
all in all what is pass in the parameter list , what will be the value of the new Message.
6.Handle.obtainMessage()
public final Message obtainMessage() { return Message.obtain(this); }
it pass it seft to Message.obtain, and get a default message with the target of the handler itself.
7.Handler's other obtainMessage()
Message obtainMessage(int what)
Message obtainMessage(int what, Object obj)
Message.obtainMessage(int what, int arg1, int arg2)
Message obtainMessage(int what, int arg1, int arg2, Object obj)
the same as Handler.obtainMessage(). but what is passed into the parameter list , what will be the new value of the new message.
8. Handler's sendMessage function
send the message to it's message queue, and it's handlerMessage(msg), will final called with the msg passed in as parameter.
9. extra
Looper.prepare
a.new messagequeue
message queue to looper.mQueue
currentthread to looper.mThread
looper to sThreadLocal.
b.myLooper, get sThreadLocal's looper
who decides which thread a handler's code works?
the messagequeue, handler send to.
a.how to define a handler's messagequeue?
Handler(Looper) this case pass one in.
Hanlder(), and other format without the looper passed in,
it's the messagequeue of current thread's looper .
it is created in the thread that runs it constructor function.(does it also belong to the thread?)
b.who decides the messagequeue' working thread?
the thread who run the messagequeue, that the code run the looper's loop.
question?
what would happen, if we define a handler's queue in one thread (that is creates it in one thread)
and run it message loop in another thread?
I havn't tried, i will try someday. maybe there will be some exception.
a complex example of using Message passing through a lot of classes.
1. BrowserActivity.onCreateContextMenu.
final HashMap<String, WebView> hrefMap = new HashMap<String, WebView>(); hrefMap.put("webview", webView);final Message msg = mHandler.obtainMessage( FOCUS_NODE_HREF, id, 0, hrefMap);webView.requestFocusNodeHref(msg);
mHandler is a Handler type member of BrowserActivity.
that's the message's target is mHandler.
the message's obj is hrefMap.
(here we get message1 name hrefMsg, and it's target is BrowserActivity.mHandler)
2.webView.requestFocusNodeHref(msg);
mWebViewCore.sendMessage(EventHub.REQUEST_CURSOR_HREF, contentX, contentY, hrefMsg);
mWebViewCore is a object of WebViewCore
(still message1 )
3. WebViewCore.sendMessage.
void sendMessage(int what, int arg1, int arg2, Object obj) { mEventHub.sendMessage(Message.obtain(null, what, arg1, arg2, obj)); }
here are two steps:
a get a new message with it's obj asmessage1(hrefMesg), and also set the what and arg1,arg2
value.
(here we got message 2 and it's target is null, with what , arg1 and arg2 set)
mEventHub is an object of EventHub
4. EventHub.sendMessage
private synchronized void sendMessage(Message msg) { if (mBlockMessages) { return; } if (mMessages != null) { mMessages.add(msg); } else { mHandler.sendMessage(msg); } }
mHandler is a object of Hander belonging to WebViewCore
so mHandler's handlerMessage will be called with msg as parameter.
5. WebViewCore.Handler.HandleMessage
case REQUEST_CURSOR_HREF: { Message hrefMsg = (Message) msg.obj; HashMap<String, WebView> hrefMap= (HashMap<String, WebView>)hrefMsg.obj; hrefMsg.getData().putString("url", nativeRetrieveHref(msg.arg1, msg.arg2)); hrefMsg.getData().putString("title", nativeRetrieveAnchorText(msg.arg1, msg.arg2)); hrefMsg.getData().putString("src", nativeRetrieveImageSource(msg.arg1, msg.arg2)); hrefMsg.sendToTarget(); break; }
here we also do two things
a. get message1 out of message2.
b. call message1's send target to it's target.
so it's send to BrowserActivity's mHandler. and BrowserActivity.mHandler.handleMessage()
will be called.
so we final came back.
we change from message1 to message 2, and final back to message1.
But what's the meaning, does it make any sense?
The most import steps are:
1.as we genereate message2 , we add new arg to it , but we doesn't change message1.
2.as we transfer message2 back to message1, we put some extra to it, which couldn't be get in BrowserActivity.