In Android, messages are often used when information is interacting within or between threads, and these basic things can make it easier and better to architect the system and avoid some low-level errors if we are familiar with its internal principles. Before learning the messaging mechanism in Android, let's look at a few classes related to messages:
1.Message
A Message object, as the name implies, is the class that records message information. There are several more important fields for this class:
A.arg1 and Arg2: We can use two fields to hold the integer value we need to pass, and in the service we can store the service ID.
B.obj: This field is an object type, and we can let the field pass a number of items to the recipient of the message.
C.what: This field can be said to be a message flag, in the message processing, we can according to the different values of this field to do different processing, similar to when we handle the button event, through switch (V.getid ()) to determine which button is clicked.
When using the message, we can create a message instance from the new message (), but Android recommends that we pass Message.obtain () or handler.obtainmessage () Gets the message object. This is not necessarily a straightforward creation of a new instance, but rather a message instance that is immediately available from the pool of messages, and is then fetched and returned to this instance. Conversely, if there is no message instance available in the pool, a new message object is given according to the parameter. By analyzing the source, it is known that the Android system instantiates 10 message objects in a messaging pool by default.
2.MessageQueue
Message Queuing, which holds the data structure of the message object and stores the message according to the "FIFO" principle. Storage is not a meaningful save, but instead the message object is concatenated in a linked list. MessageQueue objects do not need to be created by ourselves, but have looper objects to manage them, and a thread can have at most one MessageQueue. We can get the MessageQueue in the current thread through Looper.myqueue ().
3.Looper
MessageQueue manager, in a thread, if there is a Looper object, there must be a MessageQueue object, and there is only one Looper object and one MessageQueue object. In Android, except the main thread has the default Looper object, other threads have no Looper object by default. If you want our newly created thread to have a Looper object, we should first call the Looper.prepare () method and then call the Looper.loop () method. Typical usage is as follows:
- class looperthread extends thread
- {
- public handler mHandler;
- public void run ()
- {
- looper.prepare ();
Li class= "alt" > //other actions that need to be handled;
- looper.loop ();
- }
- }
If the Looper object exists in our thread, we can get it through Looper.mylooper (), and we can get the Looper object of the main thread in the current application via Looper.getmainlooper (). One thing to note in this place is that if the Looper object is in the main thread of the application, Looper.mylooper () and Looper.getmainlooper () get the same object.
4.Handler
The processor of the message. Through the handler object we can encapsulate the message object and then add the message object to the MessageQueue through SendMessage (msg), and when MessageQueue loops to the message, The Handlemessage () method of the handler object corresponding to the message object is called to process it. Because the messages are processed in the Handlemessage () method, we should write a class that inherits from Handler and then handles the operations we need in Handlemessage ().
- /**
- *
- * @author Coolszy
- * @blog Http://blog.csdn.net/coolszy
- *
- */
- public class Messageservice extends Service
- {
- private static final String TAG = "Messageservice";
- private static final int KUKA = 0;
- Private Looper Looper;
- Private Servicehandler handler;
- /**
- * Because processing messages is in Handler's Handlemessage () method, we need to write our own class
- * Inherit from the handler class, then write the function code we need in Handlemessage ()
- * @author Coolszy
- *
- */
- Private Final class Servicehandler extends Handler
- {
- Public Servicehandler (Looper Looper)
- {
- Super (Looper);
- }
- @Override
- public void Handlemessage (Message msg)
- {
- Determine which message is based on what field
- Switch (msg.what)
- {
- Case KUKA:
- Gets the obj field of the MSG. We can write the function code we need here.
- LOG.I (TAG, "The obj field of msg:" + msg.obj);
- Break
- Other cases
- Default
- Break
- }
- If our service has completed the task, stop the service
- Stopself (MSG.ARG1);
- }
- }
- @Override
- public void OnCreate ()
- {
- LOG.I (TAG, "messageservice-->oncreate ()");
- Service is run in the main thread by default, and services are typically time consuming, if
- In the main thread, it will affect the interaction between the program and the user, so the service
- Put in a separate thread to execute
- Handlerthread thread = new Handlerthread ("Messagedemothread", Process.thread_priority_background);
- Thread.Start ();
- Gets the Looper object in the current thread
- looper = thread.getlooper ();
- Create a handler object and pass the Looper over to make handler,
- Looper and MessageQueue Connect
- handler = new Servicehandler (Looper);
- }
- @Override
- public int Onstartcommand (Intent Intent, int flags, int startid)
- {
- LOG.I (TAG, "messageservice-->onstartcommand ()");
- Get a message instance from the messaging pool
- Message msg = handler.obtainmessage ();
- Arg1 the ID of the save thread in the Handlemessage () method
- We can stop the service by Stopself (Startid) method
- msg.arg1 = Startid;
- The Flag of MSG
- msg.what = KUKA;
- Here I create a Date object that assigns a value to the obj field
- In practice we can pass the object we need to handle through obj
- Date date = new Date ();
- msg.obj = date;
- Add MSG to the MessageQueue
- Handler.sendmessage (msg);
- return start_sticky;
- }
- @Override
- public void OnDestroy ()
- {
- LOG.I (TAG, "messageservice-->ondestroy ()");
- }
- @Override
- Public IBinder Onbind (Intent Intent)
- {
- return null;
- }
- }
Below we analyze how messages are handled in Android by tracking code. First put the test code:
Operation Result:
Note: In the test code we used the Handlerthread class, which is a subclass of thread, which will create the Looper object, which eliminates the hassle of writing our own thread subclasses and creating Looper.
Android messaging Mechanism (1)