Android message Handler and androidhandler

Source: Internet
Author: User

Android message Handler and androidhandler
Why does Android provide Handler?

Android recommends that you do not perform time-consuming operations in the UI thread, because this can easily cause ANR exceptions (in the Android source code, we can see that if the UI does not respond to user operations for more than 5 seconds, ANR exception will be reported ). Therefore, some time-consuming operations are completed in the Child thread. When we get the data in the Child thread, We need to display it to the UI. If there is no Handler, this will be difficult to complete. Therefore, Android provides Handler to solve the problem of sub-thread access to the UI.
Why does Android not allow access to the UI in child threads? Obviously, this is not safe, and multi-thread access to the UI is not secure (I will not detail it here if I have learned about thread mutex in the operating system ). Someone will say that we can solve this problem by setting the semaphore. In this case, the method is not impossible, because this method will complicate the logic for accessing the UI; secondly, this will reduce the access efficiency of the UI. Handler is simple and efficient. Handler communicates with the same Message.

 

Handler usage

When using Handler, You need to override the handleMessage method, accept the Message sent by the new thread in handleMessage, and handle it accordingly. In the new thread, messages are transmitted through messages. messages often carry the data to be transmitted and the type of messages. It should also be emphasized that if the current thread has logoff, you do not need to execute logoff. prepare (). If not, you need to execute logoff. prepare () in the new thread; otherwise, an error is reported. The Code is as follows:

1 public class MainActivity extends AppCompatActivity {2 private Handler mHandler = new Handler () {3 @ Override 4 public void handleMessage (Message msg) {5 switch (msg. what) 6 {7 case 1: 8 // execute the UI operation 9 break to be modified; 10 default: 11 break; 12} 13} 14 }; 15 16 @ Override17 protected void onCreate (Bundle savedInstanceState) {18 super. onCreate (savedInstanceState); 19 setContentView (R. layout. activity_main); 20 21 new Thread (new Runnable () {22 @ Override23 public void run () {// perform the time-consuming operation in the new thread 24 25 // if the current thread has logoff, you do not need to execute logoff. prepare (); 26 logoff. prepare (); 27 try {28 Thread. sleep (1000); // sleep for 1 second 29} catch (InterruptedException e) {30 e. printStackTrace (); 31} 32 33 // after the operation is complete, send a Message to notify Handler to perform UI operations 34 35 Message msg = new Message (); 36 msg. what = 1; 37 38/* This part is pseudocode. value is the value 39 Bundle data = new Bundle (); 40 data. putSerializable ("key", value); 41 msg. setData (data); 42 43 */44 45 // after the data is set, send the message 46 mHandler. sendMessage (msg); 47} 48 }). start (); 49} 50 51}

Of course, handler can also be created in a child thread. The Code is as follows:

1 private TextView TV _test; 2 3 @ Override 4 protected void onCreate (Bundle savedInstanceState) {5 super. onCreate (savedInstanceState); 6 setContentView (R. layout. handler_test_layout); 7 8 TV _test = (TextView) findViewById (R. id. TV _test); 9 10 11} 12 13 // function 14 public void click (View v) 15 {16 new Thread (new Runnable () {17 @ Override18 public void run () {19 logoff. prepare (); 20 Handler handler = new Handler (logoff. getMainLooper () {21 @ Override22 public void handleMessage (Message msg) {23 switch (msg. what) 24 {25 case :26 TV _test.setText ("receive msg"); 27} 28} 29}; 30 Message msg = new Message (); 31 msg. what = 1; 32 handler. sendMessage (msg); 33} 34 }). start (); 35}

The code above is that when you click the button, a new thread is created, handler is created in the new thread, and a message is sent and received. Note that to create a handler in a new thread, you must use Handler handler = new Handler (logoff. getmainlogoff. getMainLooper () transfers the loloin the main thread so that the handler can access the UI. The running effect is as follows:

 

 

Handler's Internal Mechanism

When Handler is created, logoff is used to establish a message loop. Therefore, the current thread must have logoff. After a Handler is created, its internal logoff and MessageQueue can work together with the Handler. Handler sends a message to the internal MessageQueue through sendMessage, while MessageQueue calls the queue. enqueueMessage (msg, uptimeMillis) method. Its source code is as follows:

 1 boolean enqueueMessage(Message msg, long when) { 2         if (msg.target == null) { 3             throw new IllegalArgumentException("Message must have a target."); 4         } 5         if (msg.isInUse()) { 6             throw new IllegalStateException(msg + " This message is already in use."); 7         } 8  9         synchronized (this) {10             if (mQuitting) {11                 IllegalStateException e = new IllegalStateException(12                         msg.target + " sending message to a Handler on a dead thread");13                 Log.w(TAG, e.getMessage(), e);14                 msg.recycle();15                 return false;16             }17 18             msg.markInUse();19             msg.when = when;20             Message p = mMessages;21             boolean needWake;22             if (p == null || when == 0 || when < p.when) {23                 // New head, wake up the event queue if blocked.24                 msg.next = p;25                 mMessages = msg;26                 needWake = mBlocked;27             } else {28                 // Inserted within the middle of the queue.  Usually we don't have to wake29                 // up the event queue unless there is a barrier at the head of the queue30                 // and the message is the earliest asynchronous message in the queue.31                 needWake = mBlocked && p.target == null && msg.isAsynchronous();32                 Message prev;33                 for (;;) {34                     prev = p;35                     p = p.next;36                     if (p == null || when < p.when) {37                         break;38                     }39                     if (needWake && p.isAsynchronous()) {40                         needWake = false;41                     }42                 }43                 msg.next = p; // invariant: p == prev.next44                 prev.next = msg;45             }46 47             // We can assume mPtr != 0 because mQuitting is false.48             if (needWake) {49                 nativeWake(mPtr);50             }51         }52         return true;53     }

Through the source code, we found that queue. enqueueMessage (msg, uptimeMillis) put the message into MessageQueue. Logoff will always process messages in MessageQueue.

 
 

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.