Android Message, MessageQueue, logoff, Handler (with example), messagequeueloading
I. Several key concepts
1. MessageQueue: a data structure. It is a message queue where messages are stored. Each thread can have at most one MessageQueue data structure. MessageQueue is not automatically created when a thread is created. A logoff object is usually used to manage the MessageQueue of the thread. When the main thread is created, a default logoff object is created, and a Message Queue is automatically created when the logoff object is created. Other non-main threads do not automatically create logoff. When necessary, they are implemented by calling the prepare function.
2. Message: the Message object, the object stored in the Message Queue. A Message Queue contains multiple messages. Obtain the object of the Message instance, usually using the static method obtain () in the Message class. This method has multiple overloaded versions to choose from; it does not necessarily create a new instance directly. Instead, it first checks whether there is any available Message instance from the Message Pool. If yes, It is retrieved and returned. If no Message instance is available in the Message Pool, a Message object is created with the given parameters. When removeMessages () is called, the Message is deleted from the Message Queue and put into the Message Pool. In addition to the above method, you can also get a Message instance through the obtainMessage () of the Handler object.
3. Logoff: the manager of MessageQueue. Each MessageQueue cannot be separated from the logoff object. The creation of the logoff object is implemented through the prepare function. At the same time, each logoff object is associated with a thread. You can obtain the logoff object of the current thread and create a MessageQueue object. Besides the default logoff for the main thread, other threads do not have MessageQueue objects by default. Therefore, messages cannot be accepted. If you need to accept it, define a Looper object (through the prepare function) by yourself, so that the thread has its own Looper object and MessageQueue data structure. Logoff extracts the Message from MessageQueue and submits it to handleMessage of Handler for processing. After the processing is complete, call Message. recycle () to put it into the Message Pool.
4. Handler: the Message processor. handler encapsulates the information to be transmitted into a Message, which is implemented by calling the obtainMessage () of the handler object and passing the Message to logoff, this is implemented through sendMessage () of the handler object. Then, logoff puts the Message into MessageQueue. When the logoff object sees that MessageQueue contains a Message, it is broadcasted. After the handler object receives the message, it calls the handleMessage () method of the corresponding handler object to process it. Ii. How to transmit messages between threads
1. The main thread sends a Message to itself.
Package test. message; import android. app. activity; import android. OS. bundle; import android. OS. handler; import android. OS. logoff; import android. OS. message; import android. view. view; import android. widget. button; import android. widget. textView; public class MainActivity extends Activity {private Button btnTest; private TextView textView; private Handler handler; @ Override public void onCreate (Bundle save DInstanceState) {super. onCreate (savedInstanceState); setContentView (R. layout. main); btnTest = (Button) this. findViewById (R. id. btn_01); textView = (TextView) this. findViewById (R. id. view_01); btnTest. setOnClickListener (new View. onClickListener () {@ Override public void onClick (View arg0) {logoff = logoff. getMainLooper (); // The loler object of the main thread // handler is created for the Looper object of the main thread. // Therefore, the Message sent by the handler will be passed. The MessageQueue of the main thread. Handler = new MyHandler (lofter); handler. removeMessages (0); // construct the Message object // The first parameter: the specified message code, it makes no sense for handler to selectively receive // The second three parameters // The fourth parameter needs to encapsulate the object Message msg = handler. obtainMessage (, 1, "message sent by the main thread"); handler. sendMessage (msg); // send Message});} class MyHandler extends Handler {public MyHandler (Looper loler) {super (loid);} public void handleMessage (Message msg) {super. handleMessage (msg); textView. setText ("I am the Handler of the main thread and received the message:" + (String) msg. obj );}}}
2. Other threads send messages to the main thread
Package test. message; import android. app. activity; import android. OS. bundle; import android. OS. handler; import android. OS. logoff; import android. OS. message; import android. view. view; import android. widget. button; import android. widget. textView; public class MainActivity extends Activity {private Button btnTest; private TextView textView; private Handler handler; @ Override public void onCreate (Bundle save DInstanceState) {super. onCreate (savedInstanceState); setContentView (R. layout. main); btnTest = (Button) this. findViewById (R. id. btn_01); textView = (TextView) this. findViewById (R. id. view_01); btnTest. setOnClickListener (new View. onClickListener () {@ Override public void onClick (View arg0) {// it can be seen that a thread is started here to operate on message encapsulation and sending. // in this way, the sending of the original main thread becomes the sending of other threads. Is it simple? Haha new MyThread (). start () ;}});} class MyHandler extends Handler {public MyHandler (Looper loler) {super (loid);} public void handleMessage (Message msg) {super. handleMessage (msg); textView. setText ("I am the Handler of the main thread and received the message:" + (String) msg. obj) ;}} // added a Thread class MyThread extends Thread {public void run () {Looper lods = looper. getMainLooper (); // The loler object of the main thread // handler is created for the loler object of the main thread. // Therefore, this hand The Message sent by ler will be passed to the MessageQueue of the main thread. Handler = new MyHandler (lofter); // construct the Message object // The first parameter: the message code specified by the user, it makes no sense for handler to selectively receive // The second three parameters // The fourth parameter needs to encapsulate the object Message msg = handler. obtainMessage (, 1, "other threads have sent messages"); handler. sendMessage (msg); // send message }}}
3. The main thread sends a Message to other threads.
Package test. message; import android. app. activity; import android. OS. bundle; import android. OS. handler; import android. OS. logoff; import android. OS. message; import android. view. view; import android. widget. button; import android. widget. textView; public class MainActivity extends Activity {private Button btnTest; private TextView textView; private Handler handler; @ Override public void onCreate (Bundle save DInstanceState) {super. onCreate (savedInstanceState); setContentView (R. layout. main); btnTest = (Button) this. findViewById (R. id. btn_01); textView = (TextView) this. findViewById (R. id. view_01); // start the thread new MyThread (). start (); btnTest. setOnClickListener (new View. onClickListener () {@ Override public void onClick (View arg0) {// here, the Message msg = handler has been instantiated when the handler is instantiated during thread startup. obtainMessage (, 1, "Master The message sent by the thread "); handler. sendMessage (msg) ;}});} class MyHandler extends Handler {public MyHandler (Looper loler) {super (loid);} public void handleMessage (Message msg) {super. handleMessage (msg); textView. setText ("I am the Handler of the main thread and received the message:" + (String) msg. obj) ;}} class MyThread extends Thread {public void run () {loid. prepare (); // create the logoff object of the thread to receive messages. // note: the handler is defined in the main thread, // The handler object is directly used, Is it looking for, where is it instantiated? // You can see it now ??? Haha, it cannot be instantiated at the beginning, because the logoff object of this thread does not exist yet. Now it can be instantiated. // here logoff. mylohand() obtains the loler object of the thread. handler = new ThreadHandler (lohand. mylogoff (); // is there any doubt about this method? // It is actually a loop in which messages are retrieved from MessageQueue cyclically. // Do you know that you have new messages ??? Logoff. loop () ;}// define the Message processing class ThreadHandler extends Handler {public ThreadHandler (Looper loler) {super (lods);} public void handleMessage (Message msg) in the Thread class) {// here, the Message in MessageQueue in this thread is processed. // here we return a Message to the main thread, handler = new MyHandler (loler. getMainLooper (); Message msg2 = handler. obtainMessage (, 1, "subthread Received:" + (String) msg. obj); handler. sendMessage (msg2 );}}}}
4. other threads send messages to themselves
Packagetest. message; import android. app. activity; import android. OS. bundle; import android. OS. handler; import android. OS. logoff; import android. OS. message; import android. view. view; import android. widget. button; import android. widget. textView; public class MainActivity extendsActivity {privateButton btnTest; privateTextView textView; privateHandler handler; @ Override publicvoid onCreate (Bundle savedInstanceState) {super. onCreate (savedInstanceState); setContentView (R. layout. main); btnTest = (Button) this. findViewById (R. id. btn_01); textView = (TextView) this. findViewById (R. id. view_01); btnTest. setOnClickListener (newView. onClickListener () {@ Override publicvoid onClick (View arg0) {// start the thread newMyThread (). start () ;}}) ;}classmyhandler extendsHandler {publicMyHandler (Looper loler) {super (lolic) ;} publicvoid handleMessage (Message msg) {super. handleMessage (msg); textView. setText (String) msg. obj) ;}} classMyThread extendsThread {publicvoid run () {Looper. prepare (); // create the logoff object of this thread // here logoff. mylohand() obtains the loler object of the thread. handler = new ThreadHandler (lohand. mylofter (); Message msg = handler. obtainMessage (, 1, "Myself"); handler. sendMessage (msg); logoff. loop () ;}// define the Message processing class classThreadHandler extendsHandler {publicThreadHandler (Looper loler) {super (loler);} publicvoid handleMessage (Message msg) in the Thread class) {// here, the Message in MessageQueue in this thread is processed. // here, we return a Message to the main thread. // Add it to the thread to check whether the Message is sent by the thread itself. if (msg. what = 1 & msg. obj. equals ("Myself") {handler = new MyHandler (logoff. getMainLooper (); Message msg2 = handler. obtainMessage (, 1, "Notification main thread: I received the Message that I sent myself"); handler. sendMessage (msg2 );}}}}}