Android message mechanism (Handler message transmission mechanism)

Source: Internet
Author: User

Android message mechanism (Handler message transmission mechanism)

For the sake of performance optimization, android UI operations are not thread-safe, which means that if multiple threads operate on the UI component concurrently, thread security issues may occur and this problem is not solved,

From the perspective of development, Handler is the upper-layer interface of the Android message mechanism, so that you only need to interact with Handler during development.
Handler is easy to use. It can be used to easily switch a task to the thread where the Handler is located for execution. Many believe that
The function of Handler is to update the UI. This is true, but updating the UI is only a special use case of Handler. Specifically, it is like this:
Sometimes it is necessary to perform time-consuming I/O operations in the Child thread, such as reading files or accessing the network. After time-consuming operations are completed, some changes may need to be made on the UI, because
Android development specification restrictions, we cannot access the UI control in the Child thread, otherwise it will trigger a program exception, this time through Handler can be updated
UI operations are switched to the main thread for execution. Therefore, Handler is specifically used to update the UI, which is often used by developers to update the UI.

Android message mechanism mainly refers to the Handler running mechanism. Handler running requires the underlying MessageQueue and
Logoff support. The Chinese Translation of MessageQueue is a message queue, as the name suggests,
It stores a group of messages internally and provides external insertion and deletion in the form of queues. Although it is called a message queue, its internal storage structure is not a real queue,
Instead, the message list is stored using the data structure of a single linked list. Logoff can be understood as a message loop. Because MessageQueue
It is just a storage unit of messages. It cannot process messages, and logoff fills in this function.
It will query whether there are new messages in an infinite loop. If yes, it will process the messages; otherwise, it will wait. There is also a special concept in logoff, that is
ThreadLocal is not a thread. It stores data in each thread. We know that Handler
When being created, The logoff System of the current thread is used to construct the message loop system. How does the Handler obtain the Logoff of the current thread?
This requires ThreadLocal. ThreadLocal can store and provide data in different threads without interference.
You can easily obtain the Logoff of each thread. Of course, it should be noted that the thread does not have logoff by default. If Handler is required, it must be created for the thread.
Logoff. We often mention the main thread, also called the UI thread, which is the ActivityThread. The ActivityThread will be initialized when it is created.
Loose. This is why Handler can be used by default in the main thread. The above section describes the android message transmission mechanism in teacher Ren yugang's book. I think the description is very clear.

Android rules: only the UI thread (main thread) is allowed to modify the UI components in the Activity.

However, in applications, you sometimes need to perform operations on the UI, such as obtaining the SMS verification code and having a countdown. Therefore, you need to use the Handler message transmission mechanism.

Handler class Introduction

[1] function:
1. Send messages in the newly started thread
2. obtain and process messages in the main thread
Main Method
Method Signature
Public void handleMessage (Message msg)

The subclass object receives information through this method.

Public final boolean sendEmptyMessage (int what)

Send a message containing only what values

Public final boolean sendMessage (Message msg)

Send a message to Handler and receive it by handleMessage

Public final boolean hasMessages (int what)

Monitor whether there are any messages in the Message Queue
Public final boolean hasMessages (int what, Objectobject)

Monitor whether there are any messages in the message queue and the object attribute is the message of the specified object.

Public final boolean post (Runnable r)
Add a thread to the Message Queue

The following countdown example

Public class MainActivity extends Activity {private Button button; private int count; private Message message; private static final int TIME_DESC = 0; private Handler handler = new Handler () {@ Override public void handleMessage (Message msg) {super. handleMessage (msg); switch (message. what) {case TIME_DESC: String time = (String) message. obj; button. setText (time); break ;}};@ Override protected void onCreate (Bundle savedInstanceState) {super. onCreate (savedInstanceState); setContentView (R. layout. activity_main); button = (Button) findViewById (R. id. button); button. setOnClickListener (new View. onClickListener () {@ Override public void onClick (View v) {count = 60; new Thread (new Runnable () {@ Override public void run () {while (count> 0) {count --; try {Thread. sleep (1000);} catch (InterruptedException e) {e. printStackTrace ();} message = new Message (); message. obj = count + seconds; message. what = TIME_DESC; handler. sendMessage (message );}}}). start ();}});}}

The above code is simplified as follows:

Public class MainActivity2 extends Activity {private Button button; private int count; private Message message; private static final int TIME_DESC = 0; private Handler handler = new Handler () {@ Override public void handleMessage (Message msg) {super. handleMessage (msg); switch (message. what) {case TIME_DESC: count --; button. setText (count + second); if (count> 0) {handler. sendEmptyMessage (TIME_DESC); try {Thread. sleep (1000);} catch (InterruptedException e) {e. printStackTrace () ;}} break ;}};@ Override protected void onCreate (Bundle savedInstanceState) {super. onCreate (savedInstanceState); setContentView (R. layout. activity_main); button = (Button) findViewById (R. id. button); // message initialization message = new Message (); button. setOnClickListener (new View. onClickListener () {@ Override public void onClick (View v) {count = 60; handler. sendEmptyMessage (TIME_DESC );}});}}
Logoff Overview

The logoff class in Android is a class used to encapsulate message loops and message queues. It is used to process messages in android threads. Handler can be seen as a tool class used to insert messages to a message queue.

(1) The logoff class is used to enable a message loop for a thread.
By default, the new thread in android does not enable the message loop. (Except for the main thread, the main thread system automatically creates a logoff object for it to enable message loop .)
The logoff object stores messages and events through MessageQueue. A thread can have only one logoff corresponding to one MessageQueue.

(2) The Handler object is usually used to interact with logoff. Handler can be seen as an interface of logoff to send messages to a specified logoff and define the processing method.
By default, Handler is bound to the loose of the thread in which it is defined. For example, if Handler is defined in the main thread, it is bound to the loose of the main thread.
MainHandler = new Handler () is equivalent to new Handler (loler. myloler ()).
Looper. myLooper (): gets the looper object of the current process. Similar Looper. getMainLooper () is used to obtain the Looper object of the main thread.

(3) new Handler () directly in a non-main thread will report the following error:
E/AndroidRuntime (6173): Uncaught handler: thread Thread-8 exiting due to uncaught exception
E/AndroidRuntime (6173): java. lang. RuntimeException: Can't create handler inside thread that has not called loled. prepare ()
The reason is that no logoff object is created by default in the main thread. You must first call logoff. prepare () to enable logoff.

(4) logoff. loop (); let logoff start to work, get the message from the message queue, and process the message.

Note: Write it in logoff. the code after loop () will not be executed. This function should be a loop. When mHandler is called. getLooper (). after quit (), the loop will be aborted, and the subsequent code can be run.

(5) Based on the above knowledge, the main thread can send messages to subthreads (non-main threads.

Public class MainActivity3 extends Activity {private Button button_send; private Handler handler; @ Override protected void onCreate (Bundle savedInstanceState) {super. onCreate (savedInstanceState); setContentView (R. layout. mainthreadsend); handler = new Handler (); button_send = (Button) findViewById (R. id. button_send); button_send.setOnClickListener (new View. onClickListener () {@ Override public void onClick (View v) {MyThread thread = new MyThread (); thread. start (); handler. sendEmptyMessage (0) ;}}) ;}class MyThread extends Thread {@ Override public void run () {loid. prepare (); handler = new Handler () {@ Override public void handleMessage (Message msg) {Log. d (handle, receives the message sent by the main thread) ;}}; Looper. loop ();}}}

Result

 

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.