android--Multi-Thread handler preface

Source: Internet
Author: User

Objective

The Android messaging mechanism is another form of "event handling," a mechanism designed to solve multi-threaded problems in Android applications, where activity-initiated threads are not allowed to access the UI components in the activity. This causes the newly started thread to fail to change the property values of the UI component. But in real-world development, many places need to change the property values of UI components in a worker thread, such as downloading Web images, animations, and so on. This blog mainly introduces how handler sends and handles messages delivered on threads, and explains several ways of transmitting data to a message, and finally demonstrates it with a small demo.

Handler

Handler, which inherits directly from object, a Handler allows the sending and processing of a message or Runnable object and is associated to the MessageQueue of the main thread. Each handler has a separate thread and is associated to a thread of Message queuing, meaning that a handler has an intrinsic message queue. When an handler is instantiated, it is hosted on a thread and message queue thread, which handler messages or runnable into the message queue and extracts messages or runnable from the message queue to manipulate them.

Handler has two main functions:

    • Sends a message in a worker thread.
    • Gets and processes messages in the UI thread.

As described above, handler can put a message object or Runnable object into the message queue, and then get a message in the UI thread or execute the Runnable object, so handler to press into the message queue has two major systems, Post and SendMessage:

    • Post:post allows a Runnable object to be enqueued into the message queue. It has the following methods: Post (Runnable), Postattime (Runnable,long), postdelayed (Runnable,long).
    • Sendmessage:sendmessage allows a Message object containing the message data to be pressed into the queue of messages. Its methods are: sendemptymessage (int), sendMessage (message), Sendmessageattime (Message,long), sendmessagedelayed (message, Long).

As can be seen from the various methods above, both post and SendMessage have several methods, they can set the Runnable object and the Message object to be enqueued into the message queue, whether it is executed immediately or deferred.

  

Post

For Handler post, it passes a Runnable object to the message queue, and in this Runnable object, rewrite the run () method. In this run () method, it is common to write operations that need to be on the UI thread.

In handler, the method of post is as follows:

    • Boolean post (Runnable R): A Runnable is enqueued into the message queue, and the UI thread executes immediately after the object is fetched from the message queue.
    • Boolean postattime (Runnable r,long uptimemillis): Queues a Runnable into a message queue, which is executed at a specific time after the UI thread takes the object out of the message queue.
    • Boolean postdelayed (Runnable r,long delaymillis): Queues a Runnable into a message queue and delays delaymills seconds after the UI thread takes the object out of the message queue
    • void Removecallbacks (Runnable R): Removes a Runnable object from the message queue.

Below is a demo that explains how to modify the properties of a UI component in a newly-started thread via the handler post method:

 1 package Com.bgxt.datatimepickerdemo; 2 3 Import android.app.Activity; 4 Import Android.os.Bundle; 5 Import Android.os.Handler; 6 Import Android.view.View; 7 Import Android.widget.Button; 8 Import Android.widget.TextView; 9 public class HandlerPostActivity1 extends Activity {One private Button btnmes1,btnmes2;12 private TextView TvM ESSAGE;13//Declare a Handler object in the private static Handler handler=new Handler (); @Override17 protected void OnCreate (Bundle savedinstancestate) {super.oncreate (savedinstancestate); Setcontentview (r.layout        . message_activity);         btnmes1= (Button) Findviewbyid (r.id.btnmes1); btnmes2= (Button) Findviewbyid (r.id.btnmes2); 23 Tvmessage= (TextView) Findviewbyid (r.id.tvmessage), Btnmes1.setonclicklistener (New View.onclicklistener ()                 {@Override27 public void OnClick (View v) {28//New START a child thread 29 New THread (New Runnable () {@Override31 public void run () {32                         Tvmessage.settext ("..."); 33//above the operation will be error-able to access the UI component in the child thread, the UI component's properties must be accessed in the UI thread 34                    Use post to modify the Text property of the UI component Tvmessage Handler.post (new Runnable () {                                 @Override37 public void Run () {38 Tvmessage.settext ("Use Handler.post to send a piece of execution to the message queue in a worker thread, executed in the main thread.")                        ");                                39}40}); }42}). Start ();}44}); btnmes2.setoncli Cklistener (New View.onclicklistener () {@Override49 public void OnClick (View v) {      New Thread (Runnable () {51               @Override52 public void Run () {53//Modify the UI component using postdelayed mode Tvmes                             Sage's Text property value 54//And Delay 3S execution handler.postdelayed (new Runnable () {56                                 @Override58 public void Run () {59 Tvmessage.settext ("uses handler.postdelayed to send a piece of execution to the message queue in a worker thread, delaying 3S execution in the main thread.    ");                        60 61}62}, 3000); }64}). Start (); 65 66}67}); 68}69}

Effect Show:

One thing to note is that, for the post method, the code for the Run () method of the Runnable object is executed on the UI thread, so for this code, it is not possible to perform operations on the UI thread, as in the case of a post, such as accessing the network, Here's an example of using post to get a picture from the Internet and display it in ImageView.

 1 package Com.bgxt.datatimepickerdemo; 2 3 Import Org.apache.http.HttpResponse; 4 Import org.apache.http.client.HttpClient; 5 Import Org.apache.http.client.methods.HttpGet; 6 Import org.apache.http.impl.client.DefaultHttpClient; 7 Import Org.apache.http.util.EntityUtils; 8 9 Import android.app.activity;10 import android.app.progressdialog;11 import android.graphics.bitmap;12 Import ANDROID.GRAPHICS.BITMAPFACTORY;13 Import android.os.bundle;14 import android.os.handler;15 import Android.view.View; Import android.widget.button;17 Import android.widget.imageview;18 public class HandlerPostActivity2 extends Activity {private Button btndown;21 private ImageView ivimage;22 private static String image_path = "http:/ /ww4.sinaimg.cn/bmiddle/786013a5jw1e7akotp4bcj20c80i3aao.jpg "; ProgressDialog dialog;24//A static handler, The Handler proposal is declared static for the private static Handler handler=new Handler (); @Override27 protected void OnCreate (Bundle SavedinstancestATE) {super.oncreate (savedinstancestate); Setcontentview (r.layout.asynctask_activity); 30 31          Btndown = (Button) Findviewbyid (r.id.btndown); ivimage = (ImageView) Findviewbyid (r.id.ivsinaimage); 33 34          dialog = new ProgressDialog (this), Dialog.settitle ("hint"), dialog.setmessage ("Downloading, please later ..."); 37            Dialog.setcancelable (false); Btndown.setonclicklistener (new View.onclicklistener () {                 @Override41 public void OnClick (View v) {42//Open a sub-thread for downloading pictures 43         New Thread (New MyThread ()). Start (); 44//Display dialog box Dialog.show (); 46}47 });}49 public class MyThread implements Runnable {Wuyi @Override53 public void Run () {54//Download a picture HttpClient HttpClient = new Defaulthttpclient (); HttpGet HttpGet = New HttpGet (image_path); HttpResponse HttpResponse = null;58 try {httpresponse = Httpclient.execute (HttpGet), if (Httpresponse.getstatusline (). Getstatuscode () = =) {byte[] Data = Entityutils.tobytearray (httpResponse62. getentity ()); 63//Get a Bitmap object,                      And in order to make it accessible within the post, it must be declared as Final64 final Bitmap bmp=bitmapfactory.decodebytearray (data, 0, data.length); 65                         Handler.post (New Runnable () {@Override67 public void Run () {68//Operation UI component in post ImageView69 IV                     Image.setimagebitmap (BMP); 70}71}); 72//Hide dialog Box 73 Dialog.dismiss ();}75} catch (Exception e) {E.printstacktrac  E (); 77}78       }79 80}81} 

Effect Show:

Message

Handler if you are using SendMessage to enqueue messages into a message queue, you need to pass a message object, and in handler, you need to override the Handlemessage () method to get the message that the work line path pass. This method runs on the UI thread. Let's introduce the message below.

The message is a final class, so it cannot be inherited. The message encapsulates the messages passed in the thread, and if for general data, the message provides the GetData () and SetData () methods to get and set the data, where the manipulated data is a bundle object that provides a series of getxxx The () and setxxx () methods are used to pass the key-value pairs of the base data type, which is simple to use for basic data types and is not explained in detail here. For complex data types, such as the passing of an object is relatively complex. In the bundle provides two methods, specifically to pass the object, but these two methods also have the corresponding restrictions, need to implement a specific interface, of course, some of the android comes with the class, in fact, has implemented the two interfaces of one, can be used directly. Here's how:

    • Putparcelable (String key,parcelable value): The object class that needs to be passed implements the Parcelable interface.
    • Pubserializable (String key,serializable value): The object class that needs to be passed implements the Serializable interface.

There is another way to pass an object in the message, which is to use the value of the Obj property passed with the message, which is an object type, so that you can pass objects of any type, with the following properties of the message:

    • int arg1: Parameter one, used to pass data that is not complex, complex data is passed with SetData ().
    • int arg2: Parameter two, used to pass data that is not complex, complex data is passed with SetData ().
    • Object obj: Passes an arbitrary object.
    • int What: Defines the message code, typically used to set the flag of the message.

For a Message object, it is generally not recommended to use its construction method directly, but it is recommended to get it by using the static method of Message.obtain () or handler.obtainmessage (). Message.obtain () Gets a message object from the messages pool, and if it is empty in the message pool, a new message is instantiated using the construction method, which facilitates the exploitation of the message resource. There is no need to worry about too many messages in the message pool, it has an upper limit of 10. Handler.obtainmessage () has multiple overloaded methods, if you look at the source code, you will find that the Handler.obtainmessage () is also called Message.obtain () internally.

Since the message is the delivery of messages between threads, first use a demo to explain the usage of the message, or a regular demo of downloading an image from the Internet, using the ImageView control to show:

 1 package Com.bgxt.datatimepickerdemo; 2 3 Import Org.apache.http.HttpResponse; 4 Import org.apache.http.client.HttpClient; 5 Import Org.apache.http.client.methods.HttpGet; 6 Import org.apache.http.impl.client.DefaultHttpClient; 7 Import Org.apache.http.util.EntityUtils; 8 9 Import android.app.activity;10 import android.app.progressdialog;11 import android.graphics.bitmap;12 Import ANDROID.GRAPHICS.BITMAPFACTORY;13 Import android.os.bundle;14 import android.os.handler;15 import android.os.Message ; Import android.view.view;17 Import android.widget.button;18 import android.widget.imageview;19 public class HandlerMessageActivity1 extends Activity {private Button btndown;22 private ImageView ivimage;23 Private St atic String image_path = "Http://ww4.sinaimg.cn/bmiddle/786013a5jw1e7akotp4bcj20c80i3aao.jpg"; ProgressDialog dialog;25 private static int is_finish = 1;26 @Override28 protected void onCreate (Bundle sav        Edinstancestate) {29 Super.oncreate (Savedinstancestate), Setcontentview (r.layout.asynctask_activity), Btndown = (Button ) Findviewbyid (r.id.btndown), ivimage = (ImageView) Findviewbyid (r.id.ivsinaimage); dialog = new Pr Ogressdialog (This), Dialog.settitle ("hint message"), PNS dialog.setmessage ("Downloading, please later ..."); Dialog.setcan             Celable (false); Btndown.setonclicklistener (new View.onclicklistener () {@Override42 public void OnClick (View v) {MyThread new Thread (New). Start (); dialog.show }46})}48 Handler Handler = new Handler () {50//Get message in Handler, heavy Write Handlemessage () method @Override52 public void Handlemessage (Message msg) {53//judgment Whether the interest code is 154 if (msg.what==is_finish) {byte[] Data= (byte[]) msg.obj;56 Bitmap bmp= Bitmapfactory.decodebyteArray (data, 0, Data.length), Ivimage.setimagebitmap (BMP), Dialog.dismiss (), 59 }60}61};62 public class MyThread implements Runnable {@Override66 public vo ID run () {HttpClient HttpClient = new Defaulthttpclient (); HttpGet httpget = new HttpGet (imag E_path); HttpResponse HttpResponse = null;70 try {+ HttpResponse = HTTPCLIENT.E  Xecute (HttpGet); (Httpresponse.getstatusline (). Getstatuscode () = = () (byte[) data = Entityutils.tobytearray (httpResponse74. getentity ()); 75//Get an MES                     Sage object, set what is 176 Message msg = Message.obtain (); msg.obj = data;78                 Msg.what = is_finish;79//Send this message to the message queue in Handler.sendmessage (msg); 81         }82    } catch (Exception e) {e.printstacktrace (); 84}85}86}87} 

Display effect:

The Message.obtain () method has multiple overloaded methods, which can be broadly divided into two classes, one that does not need to pass handler objects, and for such methods, when a good message is populated, the Handler.sendmessage () method needs to be called to send the message to the message queue. The second class needs to pass a handler object, which can send a message to the message queue directly using the Message.sendtotarget () method, because there is a property Target for the private handler type in the Message object, When the obtain method passes into a handler object, it assigns a value to the target property, and when the Sendtotarget () method is called, the Target.sendmessage () method is actually called inside it.

In handler, some methods for sending empty messages are also defined, such as: sendemptymessage (int), sendemptymessagedelayed (int what,long delaymillis), It seems that these methods can send a message without using message, but if you look at the source code you will find that the inside is also a message object from the Message.obtain () method, then assign a value to the property, and finally use SendMessage () Sends a message to the message queue.

In handler, the methods associated with sending messages to a message are:

    • Message Obtainmessage (): Gets a Message object.
    • Boolean sendMessage (): Sends a Message object to the messages queue and executes immediately after the UI thread has taken the message.
    • Boolean sendmessagedelayed (): Sends a Message object to the messages queue, deferred execution after the UI thread has taken the message.
    • Boolean sendemptymessage (int): Sends an empty message object to the queue and executes immediately after the UI thread has taken the message.
    • Boolean sendemptymessagedelayed (int what,long delaymillis): Sends an empty message object to the message queue, deferred execution after the UI thread has taken the message.
    • void Removemessage (): Removes an unresponsive message from the message queue.

Here's a little demo to show you the various ways to send a message:

  1 package Com.bgxt.datatimepickerdemo;  2 3 Import android.app.Activity;  4 Import Android.os.Bundle;  5 Import Android.os.Handler;  6 Import Android.os.Message;  7 Import Android.view.View;  8 Import Android.widget.Button; 9 Import Android.widget.TextView; Ten public class HandlerMessageActivity2 extends Activity {btn1, btn2, Btn3, btn4,btn5; Rivate static TextView tvmes; The private static Handler Handler = new Handler () {@Override-public void Handlemessage (Android). Os. Message msg) {if (Msg.what = = 3| |                 msg.what==5) {tvmes.settext ("what=" + Msg.what + ", this is an empty message"), or else {20 Tvmes.settext ("what=" + Msg.what + "," + msg.obj.toString ()); 21} 22 23}; 24}; @Override protected void OnCreate (Bundle savedinstancestate) {//TODO auto-generated method Stub super.oncreate (savedinstancestate);   30      Setcontentview (R.layout.message_activity2); Tvmes = (TextView) Findviewbyid (r.id.tvmes); BTN1 = (Button) Findviewbyid (r.id.btnmessage1); BTN2 = (Button) Findviewbyid (r.id.btnmessage2); Btn3 = (Button) Findviewbyid (R.ID.BTNMESSAGE3); Btn4 = (Button) Findviewbyid (r.id.btnmessage4); Btn5 = (Button) Findviewbyid (R.ID.BTNMESSAGE5); Notoginseng Btn1.setonclicklistener (New View.onclicklistener () {@Override Click (View v) {41//Use Message.obtain+hander.sendmessage () to send a message to the new Thread (new Runnable () {@Override-public void Run () {* * * msg = Message.obtain (); Msg.what = 1; Msg.obj = "Send Message using Message.obtain+hander.sendmessage ()"; Handler.sendmessage (msg);            49} 50     }). Start (); 51} 52}); Btn2.setonclicklistener (new View.onclicklistener) {@Override-Voi                     D OnClick (View v) {58//Use Message.sendtotarget to send message the new Runnable () {60 @Override, public void Run () {message.obt Message msg = Ain (handler); Msg.what = 2; Msg.obj = "Send Message using Message.sendtotarget"; Msg.sendtotarget (); }). Start (); 68} 69});              Btn3.setonclicklistener (New View.onclicklistener () {72//Send a delay message @Override 74  public void OnClick (View v) {Runnable new Thread (new) {@Override The public void Run () {Handler.sendeMptymessage (3); }). Start (); 81} 82}); Btn4.setonclicklistener (New View.onclicklistener () {@Override voi                     D OnClick (View v) {Runnable new Thread (new) {@Override 90                          public void Run () {message.obtain Message msg = + = = = = = = = = + = = 4; 93 Msg.obj = "Send delay message using message.obtain+hander.sendmessage ()"; 94 handler.sendmessagedelayed (MSG, 3000); ). Start (); 97} 98}); Btn5.setonclicklistener (New View.onclicklistener () {101//Send a delayed empty message 102 @O                     verride103 public void OnClick (View v) {104 New Thread (new Runnable () {105 @Override106 public void Run ({107 handler.sendemptymessagedelayed (5, up); 108}109}). St Art (); 110}111}); 112}113}

Effect Show:

android--Multi-Thread handler preface

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.