Example and Analysis of Message Processing in Android

Source: Internet
Author: User

Example and Analysis of Message Processing in Android
Message Processing instance and analysis summary in Android

This article introduces the Message Processing Mechanism in Android, and provides a detailed introduction of several important types of Android Message processing, including Handler, Message, MessageQueue, logoff, Runnable, and Thread, provides two example codes for message processing, and analyzes in depth several principles that should be followed by the Android message mechanism.

What I learned from this article

With the foundation of java, Android is easy to learn. Many people have been able to develop available apps without a deep understanding of the Android message processing mechanism, many people began to want to learn about the Android message processing mechanism. the first motivation was to encounter a famous bug "CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views. ". The meaning of this bug is "only the thread that creates a view level can update this view". In more cases, it is to say "only the main thread can update the UI ".
This article explains how to use the Android message mechanism to update the UI or complete other operations from the main thread or child thread. You can learn:
1. How to Use Android messages for synchronous and asynchronous operations;
2. How to send and receive messages in the main thread and subthread;
3. How messages are processed;
4. Several principles that should be followed when using the Message Processing Mechanism of Android;
5. Source Code of two specific message processing instances.

Technical Background required for reading this article

You may need the following technical background to fully understand the content of this article. If you do not have the following background, we recommend that you first learn the relevant knowledge:
1. Java language basics
2. Java multithreading technology
3. Basic Android development knowledge

Example 1: Send messages in the main thread and child thread, and process messages in the main thread

Let's take a look at the Code. The Code address is:
Http://download.csdn.net/detail/logicteamleader/8827099
The purpose of this example is to create a Handler (Message Processing class). click the button on the interface to send messages to the Handler. the Handler can process these messages (which will be explained in detail later, message Processing is actually the result of the joint cooperation of multiple classes). Modify the UI. There are eight buttons on the interface. The effects from top to bottom are:
1. Use the post of Handler to pass a Runnable instance. The run method of this instance will run when the button is clicked;
2. Use postDelayed (Runnable r, long delayMillis) of Handler to pass a Runnable instance. The run method of this instance will be executed after delayMillis for a while;
3. Use the sendMessage method of Handler to pass a message. The message is parsed and executed in the handleMessage method of Handler;
4. Use the sendToTarget method of the Message to send a Message to the Handler who obtains the Message. The Message is parsed and executed in the handleMessage method of the Handler;
Methods 5th, 6, 7, and 8 are similar to the above four methods. The difference is that they are called in the Child thread.
The source code is as follows:

Package com. example. wxbhandlertest; import android. app. activity; import android. OS. bundle; import android. OS. handler; import android. OS. message; import android. OS. messageQueue; import android. view. view; import android. view. view. onClickListener; import android. widget. button; import android. widget. textView; import android. widget. toast;/*** @ author wxb * One of the Message Processing instances in Android ** 1. Send messages in the main thread * 1. use post * 2. use postDelay * 3. use sendMessage * 4. use Message. sentToTarget * 2. Use Handler * 1 in the Child thread. use post * 2. use postDelay * 3. use sendMessage * 4. use Message. sentToTarget */public class MainActivity extends Activity {private Runnable runnable = null; private Runnable runnableDelay = null; private Runnable runnableInThread = null; private Runnable runnableDelayInThread = null; private static TextView TV; private static TextView tvOnOtherThread; // custom Message type public final static int MESSAGE_WXB_1 = 1; public final static int MESSAGE_WXB_2 = 2; public final static int MESSAGE_WXB_3 = 3; public final static int MESSAGE_WXB_4 = 4; public final static int MESSAGE_WXB_5 = 5; private static Handler mHandler = new Handler () {@ Override public void handleMessage (Message msg) {switch (msg. what) {case MESSAGE_WXB_1: TV. setText ("invoke sendMessage in main thread"); break; case MESSAGE_WXB_2: TV. setText ("Message. sendToTarget in main thread "); break; case MESSAGE_WXB_3: tvOnOtherThread. setText ("invoke sendMessage in other thread"); break; case MESSAGE_WXB_4: tvOnOtherThread. setText ("Message. sendToTarget in other thread "); break;} super. handleMessage (msg) ;}}; @ Override protected void onCreate (Bundle savedInstanceState) {super. onCreate (savedInstanceState); setContentView (R. layout. activity_main); TV = (TextView) this. findViewById (R. id. tvOnMainThread); tvOnOtherThread = (TextView) this. findViewById (R. id. tvOnOtherThread); // method 1. post runnable = new Runnable () {public void run () {TV. setText (getString (R. string. postRunnable) ;}}; Button handler_post = (Button) this. findViewById (R. id. btnHandlerpost); handler_post.setOnClickListener (new OnClickListener () {@ Override public void onClick (View v) {mHandler. post (runnable) ;}}); // Method 2: postDelay runnableDelay = new Runnable () {public void run () {TV. setText (getString (R. string. postRunnableDelay) ;}}; Button handler_post_delay = (Button) this. findViewById (R. id. btnHandlerPostdelay); handler_post_delay.setOnClickListener (new OnClickListener () {@ Override public void onClick (View v) {mHandler. postDelayed (runnableDelay, 1000); // executed after 1 second}); // method 3: sendMessage Button btnSendMessage = (Button) this. findViewById (R. id. btnSendMessage); btnSendMessage. setOnClickListener (new OnClickListener () {@ Override public void onClick (View v) {Message msg = mHandler. obtainMessage (); msg. what = MESSAGE_WXB_1; mHandler. sendMessage (msg) ;}}); // Method 4: Message. sendToTarget Button btnSendtoTarget = (Button) this. findViewById (R. id. btnSendtoTarget); btnSendtoTarget. setOnClickListener (new OnClickListener () {@ Override public void onClick (View v) {Message msg = mHandler. obtainMessage (); msg. what = message_wxb2. msg. sendToTarget () ;}}); // send messages in other threads // 1. post runnableInThread = new Runnable () {public void run () {tvOnOtherThread. setText (getString (R. string. postRunnableInThread) ;}}; Button btnPost = (Button) this. findViewById (R. id. btnPost); btnPost. setOnClickListener (new OnClickListener () {@ Override public void onClick (View v) {new Thread () {@ Override public void run () {super. run (); mHandler. post (runnableInThread );}}. start () ;}}); // 2. postDelay runnableDelayInThread = new Runnable () {public void run () {tvOnOtherThread. setText (getString (R. string. postRunnableDelayInThread) ;}}; Button btnPostDelay = (Button) this. findViewById (R. id. btnPostDelay); btnPostDelay. setOnClickListener (new OnClickListener () {@ Override public void onClick (View v) {new Thread () {@ Override public void run () {super. run (); mHandler. postDelayed (runnableDelayInThread, 1000 );}}. start () ;}}); // 3. sendMessage Button btnSendMessage2 = (Button) this. findViewById (R. id. btnSendMessage2); btnSendMessage2.setOnClickListener (new OnClickListener () {@ Override public void onClick (View v) {new Thread () {@ Override public void run () {super. run (); Message msg = mHandler. obtainMessage (); msg. what = MESSAGE_WXB_3; mHandler. sendMessage (msg );}}. start () ;}}); // Method 4: Message. sendToTarget Button btnSendToTarget2 = (Button) this. findViewById (R. id. btnSendToTarget2); btnSendToTarget2.setOnClickListener (new OnClickListener () {@ Override public void onClick (View v) {new Thread () {@ Override public void run () {super. run (); mHandler. obtainMessage (MESSAGE_WXB_4 ). sendToTarget ();}}. start ();}});}}
Rules

After reading the code, you can understand several rules before interpreting a specific class:
First, only the thread that creates the view can update this view. Generally, the Android main thread is used to create the UI. Therefore, the UI can be updated only in the main thread;
Second, the class for processing messages is Handler, which is attached to the creation of its own thread. If Handler mHandler is created in the main thread, the messages sent to mHandler will be parsed in the main thread; if Handler sHandler is created in the Child thread, the messages sent to the sHandler will be parsed in the Child thread;
Third, there are three methods for sending messages: the post method of Handler, The sendMessage method of Handler, And the sentToTarget method of the Message. They all call the sendMessage method of Handler;
Fourth, the message method can be instant or delayed, that is, post and postDelay, as well as sendMessage and sendMessageDelayed. delayed message sending can achieve interface latency required by many users, for example, the most commonly used SplashWindow.
Fifth, the post method only needs to instantiate a Runnable interface, and does not need to overload the Handler. handleMessage method, which is easy to use;
Sixth, the Handler. handleMessage method needs to be reloaded for sendMessage and sentToTarget to parse different messages.

Handler

Handler is the most important class in Android message processing. No matter what programming language or framework, Handler classes are very important and complex, the Windows handle class was even more confusing.
Fortunately, Android Handler is easy to understand and use. It is a target class for message processing. It has two main functions: 1) It schedules the message to be executed and runnable to be executed at a certain time point in the future; 2) processes messages from different threads and performs operations.
Pay attention to the following points when using Handler:
1. Handler belongs to the thread that created it and is associated with the message loop of the thread. It is also associated with the MessageQueue of the thread.
2. Handler sends messages in two types: post and sendMessage. For usage, see the example;
3. If post is used to send a message, the Runnable contained in the message will be executed when the message is parsed;
4. If sendMessage is used to send messages, you need to reload the Handler. handleMessage method to parse different messages.

Message

Message is a Message class, which has several important attributes:
Public int what: Message Type
Public int arg1: parameter 1
Public int arg2: parameter 2
Public Object obj: Object parameters
You can customize the preceding parameters at will.
Note the following points:
1. android uses the Message Pool Mode to improve the efficiency of messages. Therefore, it generally does not apply to the new method to create messages. Instead, it uses the obtain method to obtain an instance of a Message from the Message pool. The Handler class also has the obtain method;
2. The Message has a Handler as the Target, which is generally the Handler associated with the thread where the Message is located. Therefore, when the sendToTarget method is used to send a Message, the Message is sent to its Target;

MessageQueue

MessageQueue is a message queue. A thread can have one message queue at most, which is generally not directly used by programmers. The queue entry method enqueueMessage is used to add a Message to the queue. This method is thread-safe, so that the Message processing mechanism of Android is thread-safe.
The next method of MessageQueue is used to obtain the next Message. When there is no Message, the main thread often waits for this method.

Runnable

Java interface, which represents an executable code segment, as shown below:

public interface Runnable {    /**     * Starts executing the active part of the class' code. This method is     * called when a thread is started that has been created with a class which     * implements {@code Runnable}.     */    public void run();}
Thread

Java Thread class should be familiar to everyone.

Example 2: create a message processing cycle in a child thread

The first example describes how to send messages in multiple threads and receive and process these messages in a unified manner in the main thread. The second example describes how to establish a message loop in a child thread, and send messages from the main thread to the subthread so that the subthread can process these messages.
In the second example, there are two message loops and two Handler. The main thread first sends a message to the subthread, And the subthread sends a message to the main thread after receiving the message, the main thread updates the UI after receiving the message.
The sample code is as follows:
Http://download.csdn.net/detail/logicteamleader/8827401
The source code is as follows:

Package com. example. wxbloopinthread; 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. view. view. onClickListener; import android. widget. button; import android. widget. textView; public class MainActivity extends Activity {private static TextView TV = null; // custom Message type public final static int MESSAGE_WXB_1 = 1; // create Handler private static Handler mHandler = new Handler () {@ Override public void handleMessage (Message msg) {switch (msg. what) {case MESSAGE_WXB_1: TV. setText ("sent by the main thread, sent by the subthread after receiving the message, and modified the UI by the main thread"); break;} super. handleMessage (msg) ;}}; @ Override protected void onCreate (Bundle savedInstanceState) {super. onCreate (savedInstanceState); setContentView (R. layout. activity_main); TV = (TextView) this. findViewById (R. id. textView1); // create a subthread new LooperThread (). start (); // click the Button to send the message to the subthread. Button btn = (Button) this. findViewById (R. id. btnSendMessage); btn. setOnClickListener (new OnClickListener () {@ Override public void onClick (View v) {LooperThread. sHandler. sendEmptyMessage (MESSAGE_WXB_1) ;}}); // defines the subthread static class LooperThread extends Thread {public static Handler sHandler = null; public void run () {// create a message loop logoff. prepare (); sHandler = new Handler () {public void handleMessage (Message msg) {switch (msg. what) {case MESSAGE_WXB_1: mHandler. sendEmptyMessage (MESSAGE_WXB_1); break ;}}; // enable message loop logoff. loop ();}}}

The second example uses another important class logoff, which represents the message loop processing class in Android.

Logoff

Logoff is used to create a message loop of a thread. The thread does not have a message loop by default. To create a message loop, you must call logoff first. prepare, and then call logoff in the appropriate place. loop, this loop method starts to process the messages received by this thread cyclically until the loop is stopped.
In most cases, logoff is used with Handler to receive and process messages through Handler.
Pay attention to the following points when using Logoff:
1. The main thread of Android has already created a logoff object by default. Therefore, logoff. prepare cannot be called in the main thread;
2. Both logoff. prepare and logoff. loop are static methods. Do not use new to create a logoff;

Summary

Android messages can be used in the following ways:
1. Use Handler and Runnable to send a message in real time or in a delayed manner;
2. If Handler and Message are used to send a Message in real time or delay, the Handler. handleMessage method must be reloaded;
Note the following rules:
1. Only the thread that creates the view can update this view. Generally, the Android main thread is used to create the UI. Therefore, the UI can be updated only in the main thread;
2. the class for processing messages is Handler, which is attached to the creation of its own thread. If Handler mHandler is created in the main thread, the messages sent to mHandler will be parsed in the main thread; if Handler sHandler is created in the Child thread, the messages sent to the sHandler will be parsed in the Child thread;
3. logoff is used to create a message loop of a thread. To create a message loop, you must first call logoff. prepare and then call logoff. loop in a proper place.
For specific experience, you still need to read more code.

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.