Off topic:
To say a little ashamed, the initial understanding of these three is actually in the back of the test. It wasn't long before I touched Android, and the books I learned were the "crazy Android handouts" that were better for getting started, of course, when you were learning about the handler part of the book, there were some simple examples. Later in the work need to use this MessageQueue time only to begin to really ponder the three links. If you want to have a good understanding of these three people, it is more recommended that the "deep understanding of Android volume Ⅰ." The following is an introduction and analysis of the grievances between the three are also reference to the relevant chapters of this book, is a reading notes it.
Overview:
The messaging mechanism of Android is another form of "event handling", which is primarily designed to solve multithreaded problems in Android applications--android platform only allows UI threads to modify UI components in activity. This makes it impossible for the newly-started thread to dynamically modify the property values in the interface component. But our program interface can not be a static rendering, so this must be used in this blog mentioned in the three large categories.
Simple example:Code Show:
public class Looperthreadactivity extends Activity {private final int msg_hello = 0; Private Handler Mhandler; Private Customthread mthread = null; private static final String TAG = LooperThreadActivity.class.getSimpleName (); @Override public void OnCreate (Bundle savedinstancestate) {super.oncreate (savedinstancestate); Setcontentview (R.layout.main); Mthread = new Customthread (); Mthread.start (); Button Sendbutton = (button) Findviewbyid (R.id.send_button); Final EditText Contentedittext = (EditText) Findviewbyid (R.id.content_edittext); Sendbutton.setonclicklistener (New Onclicklistener () {@Override public void OnClick (View v) { String Msgtext = Contentedittext.gettext (). toString (); SendMessage (Msgtext); } }); } private void SendMessage (String content) {Toast.maketext (this, "Send msg:" + content, 0). Show (); TODO 1. Add a message to MessageQueue//through Message.obtain () to get an empty message object from the message pool to conserve resources log.i (TAG, "-------- ----> Send msg 1. "); Message msg = mhandler.obtainmessage (Msg_hello, content); Msg.sendtotarget (); LOG.I (TAG, "------------> Send msg 2."); Message MSG2 = mhandler.obtainmessage (Msg_hello, Content + "2"); Msg2.sendtotarget (); } class Customthread extends Thread {@Override public void run () {looper.prepare (); LOG.I (TAG, "------------> Loop.pre."); Mhandler = new Handler () {public void Handlemessage (Message msg) {switch (msg.what) { Case MSG_HELLO:LOG.I (TAG, "------------> Receive MSG."); Toast.maketext (Looperthreadactivity.this, "Receive msg:" + (String) msg.obj, 0). Show (); } } }; Looper.looP (); } }}
Operation effect Show:
log results show:
Sample Result Analysis:
You can see that I did two consecutive add message data, in the results also have a good embodiment, but Looper.prepare (), and handler between the content is only executed once. This is because our custom thread customthread is only one time, and the start has been there and has not been destroyed, so Looper has been there and MessageQueue has been there, thus guaranteeing A thread can have only one Looper object . For this point below will use the source code for further explanation.
Mechanism Analysis:
As far as applications are concerned, Java applications on Android are the same on other systems, and they work by message-driven. The message-driven Android system is inseparable from the Looper, handler, and message, although not one of the more important, but the relatively prominent indeed is the looper. These classes are described in detail below.
Looper class Analysis:1.looper.prepare ();
Tracking prepare () into the Android source, we can find the following source code:
private static void Prepare (Boolean quitallowed) { if (sthreadlocal.get () = null) { throw new RuntimeException (" Only one Looper could be created per thread "); Sthreadlocal.set (New Looper (quitallowed)); }
Sthreadlocal definition:
Sthreadlocal.get () would return null unless you ' ve called prepare (). Static Final threadlocal<looper> sthreadlocal = new Threadlocal<looper> ();
From the above source, we can see that in the thread that calls prepare, a Looper object is set, and the Looper object is stored in the TLV of the calling thread. A message queue is encapsulated inside the Looper object. That is to say, prepare through the threadlocal mechanism, the looper and the calling thread are associated together.
2.looper.loop ();
Tracking Loop () Enter the source code for Android (there are some temporarily less relevant codes removed here):
public static void Loop () {final Looper me = Mylooper (); if (me = = null) { throw new RuntimeException ("No Looper; Looper.prepare () wasn ' t called on this thread. "); Final MessageQueue queue = Me.mqueue; Binder.clearcallingidentity (); Final Long ident = Binder.clearcallingidentity (); for (;;) { Message msg = Queue.next ();//might block if (msg = = null) { //No message indicates that the message queue is quitting. return; } Msg.target.dispatchMessage (msg); Msg.recycle (); }}
Through the above analysis, Looper has the following functions:
- Encapsulates a message queue.
- The prepare function binds the current looper with the thread that calls prepare (that is, the final processing thread).
- The processing thread calls loop to process messages from the message queue.
when the event source sends a message to this looper, it actually adds the message to the Looper message queue. The message is then handled by the processing that is bound to and Looper.
Handler class Analysis:
Learn handler first come to know some of the members included in the handler:
Final MessageQueue mqueue;final Looper mlooper;final Callback mcallback;
In the handler class, its constructor will eventually point the message queue variable in the handler to the Looper message queue. Because it is pointed, the message queue in handler is actually a looper message queue.
Looper and Handler's synchronization relationship description andintroduction of Handlerthread:
There is a synchronous relationship between Looper and handler. There is no too much of a synchronization between them, and if you want to know, see the 128th page of "in- depth understanding of Android volume Ⅰ." I hereby only put forward a reminder point: Because Handlerthread perfectly solves the Looper and handler synchronization process may occur in the null pointer anomalies, so in the future development process, we still use Handlerthread bar. Of course, if you don't want to use it, use the lock mechanism to build your code, but it's possible that you'll have to repeat the wheel.
References:
1. "Crazy Android Handout"
2. "In- depth understanding of Android volume Ⅰ"
3. Network resources: http://www.cnblogs.com/codingmyworld/archive/2011/09/14/2174255.html
4. Network resources: http://www.cnblogs.com/bastard/archive/2012/06/08/2541944.html
5. Network resources:http://blog.csdn.net/mylzc/article/details/6771331
Epilogue:
Although already "confused" to the end, but the understanding of Looper, handler and message did go a big step. I hope you have gained some benefit from reading this article.
An analysis of the message processing mechanism of Android--looper,handler and message