Android's understanding of the Handle Mechanism

Source: Internet
Author: User

Android's understanding of the Handle Mechanism
1. Important references
[References]
Currently, the content in the following URLs is of good quality and you do not need to read other URLs.
1. android message mechanism
Android message mechanism (I)
I. Role description
1. loue: A thread can generate a loue object to manage the Message Queue in this thread ).
2. Handler: You can construct a Handler object to communicate with logoff, so as to push new messages to the Message Queue, or receive messages sent by logoff (retrieve from Message Queue.
3. Message Queue: used to store messages placed by threads.
4. thread: the UI thread is usually the main thread, and Android will create a Message Queue for it when starting the program.
Each thread can contain a loose object and a MessageQueue data structure. In your application, you can define the sub-category of Handler to receive messages sent by logoff.

In your Android program, when a new Thread is created or executed, the Message Loop is not automatically created.
Android does not have the Global Message Queue data structure. For example, objects in different APK cannot exchange messages through the Massage Queue ). For example, the Handler object of thread A can transmit messages to other threads, let other threads such as B or C send messages to thread A (stored in the Message Queue of thread A (// how to understand ?)).
Only the objects to which thread A belongs can process the messages in the Message Queue of thread.
You can use logoff. mylogoff to obtain the logoff object of the current thread.
MHandler = new EevntHandler (Looper. myloler () can be used to construct the Handler object of the current thread. EevntHandler is the sub-class of the Handler implemented by itself.
Use mHandler = new EevntHandler (Looper. getMainLooper (); the Handler object that can be generated to process the main thread; among them, EevntHandler is the sub-class of the Handler implemented by itself.


The description may be too similar. The following are some examples:
Ii. Example
1. message transmission between different components in the same thread
The logoff class is used to manage Message Exchange between objects in a specific thread ). Your application can generate many threads. A thread can have many components, which often need to exchange messages with each other. If you need this, you can construct a logoff object for the thread to manage message exchange. The logoff object creates a MessageQueue data structure to store messages (including UI events or System events) sent from each object ). For example:

Each thread can contain a loose object and a MessageQueue data structure. In your application, you can define the sub-category of Handler to receive messages sent by logoff.

Message transmission between different components in the same thread:

Public class Activity1 extends Activity implements OnClickListener {Button button = null; TextView text = null; @ Override protected void onCreate (Bundle savedInstanceState) {super. onCreate (savedInstanceState); setContentView (R. layout. activity1); button = (Button) findViewById (R. id. btn); button. setOnClickListener (this); text = (TextView) findViewById (R. id. content);} public void onClick (View v) {switch (v. getId () {case R. id. btn: // component 1 loose logoff = logoff. myLooper (); // obtain the looper MyHandler mHandler = new MyHandler (loler) in the current thread ); // construct a handler so that it can communicate with logoff. // components such as buton can be sent to logoff by mHandler and placed in messageQueue. At the same time, mHandler can accept mHandler from logoff. removeMessages (0); String msgStr = "communication between different main threads and components: Message from button"; Message m = mHandler. obtainMessage (1, 1, 1, msgStr); // construct the mHandler of the message to be passed. sendMessage (m); // send a message: the system will automatically call the handleMessage method to process the message break;} private class MyHandler extends Handler {public MyHandler (Looper lomessage) {super (logoff) ;}@ Override public void handleMessage (Message msg) {// process the Message text. setText (msg. obj. toString (); // component 2 }}}

Note:
When this program is started, the current thread (that is, the main thread) has generated a loose object and a MessageQueue data structure.
Lorule = lorule. mylorule ();

Call the static mylogoff () function of the logoff class to obtain the logoff object in the current thread.

MHandler = new MyHandler (logoff );

Construct a MyHandler object to communicate with logoff. Activity and other objects can send messages to logoff through the MyHandler object, and then put them into MessageQueue. The MyHandler object also plays the role of Listener and can receive messages sent by the logoff object.
Message m = mHandler. obtainMessage (1, 1, 1, obj );

Construct a Message object and store the data in the object.
MHandler. sendMessage (m );

The mHandler object is used to send the message m to logoff and put it in MessageQueue.
At this point, when the logoff object sees a message m in MessageQueue, it will be broadcast out. When the mHandler object receives this message, it will call its handleMessage () function for processing, the output is "This my message! "On the screen,


2. Android Message Mechanism 2

Android message processing mechanism (2)

Role Overview (Review ):

(1) The UI thread is usually the main thread, and Android will create a MessageQueue for it when starting the program.

(2) Of course, a logoff object is required to manage the MessageQueue.

(3) we can construct a Handler object to push new messages to the Message Queue, or receive messages sent by loler (retrieve from Message Queue.

(4) the Handler object of thread A can be passed to other threads so that other threads B or C can send messages to thread A (stored in the Message Queue of thread ).

(5) Only the object to which thread A belongs can process the messages in the Message Queue of thread.

The subthread transmits a message to the main Thread publicclass Activity2extends Activityimplements OnClickListener {Button button = null; TextView text = null; MyHandler mHandler = null; thread Thread thread; @ Override protectedvoid onCreate) {super. onCreate (savedInstanceState); setContentView (R. layout. activity1); button = (Button) findViewById (R. id. btn); button. setOnClickListener (this); text = (TextView) findViewById (R. id. content);} publicvoid onClick (View v) {switch (v. getId () {case R. id. btn: thread = new MyThread (); thread. start (); break ;}} privateclass MyHandlerextends Handler {public MyHandler (low.lodid) {super (low. B ;}@ Override publicvoid handleMessage (Message msg) {// process the Message text. setText (msg. obj. toString () ;}} privateclass MyThreadextends Thread {@ Override publicvoid run () {Looper curloworkflow = Looper. myloopers (); Loopers mainloopers = loopers. getMainLooper (); String msg; if (curLooper = null) {mHandler = new MyHandler (mainloler); msg = "curLooper is null ";} else {mHandler = new MyHandler (curloler); msg = "This is curloler";} mHandler. removeMessages (0); Message m = mHandler. obtainMessage (1, 1, 1, msg); mHandler. sendMessage (m );}}}

Note:

Android automatically creates a Message Queue for the main thread. No Message Queue is created in this child thread. Therefore, the value of mylogoff is null, while the value of mainlogoff points to the logoff in the main thread. Therefore, execute:

MHandler = new MyHandler (mainloler );

This mHandler belongs to the main thread.

MHandler. sendMessage (m );

Store m messages in the Message Queue of the main thread. When mainloue sees a Message in the Message Queue, it will process the Message. Therefore, the main thread executes the mHandler handleMessage () to process the Message.

3. message Mechanism for Android thread Communication
Http://www.javafun.cn/viewthread.php? Tid = 15174,

There is also the concept of multithreading in Android. in C/C ++, sub-threads can be a function, generally a function with a loop to process some data, the priority thread is only a complex operation process, so it may not need a while loop. The operation is complete, the function is complete, and the thread is destroyed. For the threads to be controlled, we generally associate with mutex locks to control the thread progress. Generally, we create subthreads, a thread is very common, it is the thread with a message loop.
Message loop is a very useful thread method. I used C to implement a message Loop Mechanism in Linux, add data to the message queue, and then asynchronously wait for the message to return. When the message queue is empty, the thread is suspended and waiting for new messages to be added. This is a common mechanism.
In Android, threads here are divided into threads with message loops and threads without message loops. Threads with message loops generally have a logoff, a new concept of android. Our main thread (UI thread) is a message loop thread. To address this message loop mechanism, we introduce a new mechanism Handle. If we have a message loop, we need to send corresponding messages to the message loop, custom messages generally have their own processing, message sending and clearing, and message processing. These are encapsulated in Handle. Note that Handle is only for those threads with logoff, whether it's a UI thread or a sub-thread, as long as you have logoff, I can add something to your message queue and handle it accordingly.
However, there is another point here, that is, as long as it is about the UI, it cannot be placed in the Child thread, because the child thread cannot operate the UI, only data, system, and other non-UI operations can be performed.
So under what circumstances can our sub-thread be regarded as a thread with logoff? How can we get the logoff handle?
Logoff. mylogoff (); obtain the current Logoff
Lopper. getmainlopper () to obtain the Lopper of the UI thread
Let's take a look at the initialization function of Handle. If there is no parameter, it uses the current logoff by default. If there is a logoff parameter, it uses the Logoff of the corresponding thread.
If a thread calls logoff. prepare (), then the system automatically creates a message queue for this thread, and then calls logoff. loop (); then it enters the message loop. After that, you can send, retrieve, and process messages. In this case, Handle can be used to send messages and process messages, provided that our Hanle knows the Logoff of this subthread, however, if you are not running logoff in a sub-thread. mylogoff () is generally not accessible to the Logoff of sub-threads.

public void run() {            synchronized (mLock) {                Looper.prepare();               //do something            }            Looper.loop();        }
So many people do this: I create a handle directly in the Child thread, and then send messages in the Child thread. In this way, the meaning of Multithreading is lost.
class myThread extends Thread{             private EHandler mHandler ;             public void run() {                 Looper myLooper, mainLooper;                 myLooper = Looper.myLooper ();                mainLooper = Looper.getMainLooper ();                String obj;                if (myLooper == null ){                         mHandler = new EHandler(mainLooper);                         obj = "current thread has no looper!" ;                }                else {                     mHandler = new EHandler(myLooper);                     obj = "This is from current thread." ;                }                mHandler .removeMessages(0);                Message m = mHandler .obtainMessage(1, 1, 1, obj);                mHandler .sendMessage(m);             }  }
Other threads can be used to control our handle. private EHandler mHandler can be put out, so that our sending and processing messages can be defined outside, in this way, the program code is more beautiful and the structure is clearer.
For any Handle, a function must be reloaded.
Public void handleMessage (Message msg)
This function is our message processing. How to Handle it depends on you. Then, we can use obtainMessage and sendMessage to generate and send messages. removeMessages (0) can be used to clear message queues. Google is so intelligent that it is easier to write code when such a framework is created.
Sometimes, our sub-threads want to change the UI. In this case, do not modify the sub-thread to obtain the Logoff of the UI thread, and then send the message.
Let's look at the source code of Goole Music App.
In MediaPlaybackActivity. java, let's take a look at the following two sentences in OnCreate:
mAlbumArtWorker = new Worker("album art worker");        mAlbumArtHandler = new AlbumArtHandler(mAlbumArtWorker.getLooper());

Obviously, these two statements construct a subthread. In addition, this sub-thread is still a logoff sub-thread. Here we use mAlbumArtWorker. getLooper () is a function, because we know that there is only one way to get the Looper of the sub-thread: it is to call Looper in the sub-thread. myloe (), and this function needs to be called after perpare to get the correct Looper. But here he uses getLooper and does not know how it is implemented?
Here is a rough idea. We call the mylogoff () method after the prepare of the sub-thread and save it in a member variable. This getlogoff will return this thing, but here we will encounter a very prominent problem of multithreading, synchronization. We call mAlbumArtWorker in the parent thread. getloe (), but if we want to return the correct loe, we must require our subthread to run prepare. But how can we ensure that this is actually executed by the subthread?
We can see how Google achieves this?
private class Worker implements Runnable {        private final Object mLock = new Object();        private Looper mLooper;                /**         * Creates a worker thread with the given name. The thread         * then runs a [[email protected]][email protected][/email] android.os.Looper}.         * @param name A name for the new thread         */        Worker(String name) {            Thread t = new Thread(null, this, name);            t.setPriority(Thread.MIN_PRIORITY);            t.start();            synchronized (mLock) {                while (mLooper == null) {                    try {                        mLock.wait();                    } catch (InterruptedException ex) {                    }                }            }        }                public Looper getLooper() {            return mLooper;        }                public void run() {            synchronized (mLock) {                Looper.prepare();                mLooper = Looper.myLooper();                mLock.notifyAll();            }            Looper.loop();        }                public void quit() {            mLooper.quit();        }    }
We know that the constructor of A Thread class is completed in the main thread, So we create a thread in our Worker constructor, and then let this thread run, this thread is created to specify a Runnabl. here our Worker itself is called in the main thread t. start (); after that, we have created a sub-thread and started to execute the run method of work. Then the following code is very artistic:
synchronized (mLock) {                while (mLooper == null) {                    try {                        mLock.wait();                    } catch (InterruptedException ex) {                    }                }            }

We started to wait for our sub-thread to assign values to mLooper. If no value is assigned, we will continue to wait. After our sub-thread runs the run method, after assigning values to mLooper, it notifies the worker that the wait in the function is sufficient, and then our constructor can be completed, so we say:
MAlbumArtWorker = new Worker ("album art worker ");
This statement is itself congested. It creates a subthread, enables the subthread, and waits until the subthread assigns a value to mLooper. After the assignment is complete, this function returns, in this way, we can ensure that the Logoff of our sub-threads is absolutely correct. This idea is very creative. Worth learning

4. How to Use Handler in Android-update the interface in the Child thread

Ii. knowledge points

I. knowledge points
1. handler should be created by the message processing thread.

2. handler is associated with the thread used to create it, and is only associated with the thread used to create it. Handler runs in the thread where it is created. Therefore, if a time-consuming operation is performed in handler, the thread that creates it will be blocked.
[Source] from:
Ii. knowledge points
1. Android threads are divided into threads with message loops and threads without message loops. Threads with message loops generally have a logoff. The main thread (UI thread) is a message loop thread.

2,
Logoff. mylogoff (); // obtain the current Logoff
Lopper. getmainlopper () // obtain the Lopper of the UI thread

3. Handle's initialization function (constructor). If there is no parameter, it uses the current Looper by default. If there is a Looper parameter, it uses the Looper of the corresponding thread.

4. If logoff is called in a thread. prepare (), then the system automatically creates a message queue for this thread, and then calls logoff. loop (); then it enters the message loop. After that, you can send, retrieve, and process messages. [Source] From: http://www.javafun.cn/viewthread.php? Tid = 1517

3. Application Instances
3.1handler transmits the message. [Application Example 1]
 

Package com. android. tutor; import java. util. timer; import java. util. timerTask; import android. app. activity; import android. OS. bundle; import android. OS. handler; import android. OS. message; public class HandlerDemo extends Activity {// title provides variables for the setTitle method. For convenience, I have set the int type private int title = 0; private Handler mHandler = new Handler () {public void handleMessage (Message msg) {switch (msg. what) {case 1: updateTitle (); break ;};}; public void onCreate (Bundle savedInstanceState) {super. onCreate (savedInstanceState); setContentView (R. layout. main); Timer timer = new Timer (); timer. scheduleAtFixedRate (new MyTask (), 1, 5000);} private class MyTask extends TimerTask {@ Override public void run () {Message message = new Message (); message. what = 1; mHandler. sendMessage (message) ;}} public void updateTitle () {setTitle ("Welcome to Mr Wei's blog" + title); title ++ ;}}
The above Code defines Handler members directly in the main thread. In the child thread, messages are sent to the main thread through the handler of the main thread. The procedure is as follows:
1. Define handler in the main thread and implement the handleMessage method for this handler.
2. Call the handler of the main thread in the Child thread and send the message through its sendMessage method.

3.2handler another way to use Handler to communicate between threads is to use Handler to transmit a runnable object instead of a message.
[Application Example 3]

Procedure
1. Define the Handler object in the main thread
2. Construct a runnable object to implement the runnable method for this object, and perform some time-consuming operations in this method.
3. Use the Handler object post (runnable) object in the Child thread.

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.