Android Handler multi-threaded detailed _android

Source: Internet
Author: User
Tags message queue

android--Multi-Thread handler

Objective

The Android messaging mechanism is another form of "event handling", which is primarily designed to address the problem of multithreading in Android applications, where the newly initiated threads of activity are not allowed to access the UI components of that activity. This causes the newly started thread to be unable to change the property values of the UI component. But in actual development, many places need to change the UI component's attribute value in the worker thread, for example downloading the network picture, the animation and so on. This blog is mainly about how handler sends and handles messages delivered on threads, and explains several ways of transmitting data, which will be demonstrated by small demos.

Handler

Handler, which inherits directly from object, a Handler allows the message or Runnable object to be sent and processed, and is associated with the MessageQueue of the main thread. Each handler has a separate thread and is associated with a thread in a message queue, meaning that a handler has an intrinsic message queue. When instantiating a handler, it is hosted on a thread and Message Queuing thread that handler messages or runnable into message queues and takes messages or runnable out of message queues to manipulate them.

Handler has two main functions:

Sends a message in a worker thread.

Gets and processes messages in the UI thread.

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

Post:post allows a Runnable object to be queued to a message queue. Its methods are: Post (Runnable), Postattime (Runnable,long), postdelayed (Runnable,long).

Sendmessage:sendmessage allows a message object that contains messages data to be pressed into a message queue. Its methods are: sendemptymessage (int), SendMessage (message), Sendmessageattime (Message,long), sendmessagedelayed (message, Long).

From the above methods, it can be seen that both post and SendMessage have a variety of methods, they can set the Runnable object and message object to be queued to the queue, whether to execute immediately or delay execution.

Post

For Handler post, it passes a Runnable object to the message queue, and in this Runnable object, overrides the Run () method. It is generally written in this run () method that needs to be done on the UI thread.

In handler, the methods for post methods are:

Boolean post (Runnable R): A Runnable is queued to a message queue, which is executed immediately after the UI thread extracts the object 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 extracts the object from the message queue.

Boolean postdelayed (Runnable r,long delaymillis): Queues a Runnable into a message queue, after which the UI thread takes the object out of the message queue, delaying delaymills second execution

void Removecallbacks (Runnable R): Removes a Runnable object from the message queue.

The following is a demo that explains how to modify the properties of a UI component in a newly-launched thread by handler the Post method:

Package Com.bgxt.datatimepickerdemo;
Import android.app.Activity;
Import Android.os.Bundle;
Import Android.os.Handler;
Import Android.view.View;
Import Android.widget.Button;

Import Android.widget.TextView;
 public class HandlerPostActivity1 extends activity {private Button btnmes1,btnmes2;
 Private TextView tvmessage;
 
 Declares a Handler object private static Handler handler=new Handler ();
 @Override 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);
 Tvmessage= (TextView) Findviewbyid (r.id.tvmessage);  Btnmes1.setonclicklistener (New View.onclicklistener () {@Override public void OnClick (View v) {//newly started a child thread
   Thread (New Runnable () {@Override public void run () {//Tvmessage.settext ("..."); The above action will not be able to access the UI component in the child thread, the properties of the UI component must be accessed in the UI thread///post to modify the Tvmessage Text property of the UI component Handler.post (The new Runnable () {@Override public void run () {Tvmessage.settext () executes in the main thread using Handler.post to send a section of execution into a message queue in a worker thread.   
    ");    
   }
   });
  }). Start ();
 
 }
 }); Btnmes2.setonclicklistener (New View.onclicklistener () {@Override public void OnClick (View v) {New Thread (new Ru Nnable () {@Override public void run () {//Modify the Text property value of the UI component Tvmessage using postdelayed method//And delay 3S execution HANDLER.P Ostdelayed (New Runnable () {@Override public void run () {Tvmessage.settext ("using handler.postdelayed to send in worker threads Send a paragraph execution to the message queue, delaying 3S execution in the main thread. 
    
    ");   
   }, 3000);
  
  }). Start ();
 }
 }); }
}

Effect Display:

It is worth noting that, for the post method, the code for the Runnable object's run () method is executed on the UI thread, so for this piece of code, the operation on the UI thread cannot be performed as a post, such as access to the network, Here's an example of using post to get a picture from the Internet and display it in ImageView.

Package Com.bgxt.datatimepickerdemo;
Import Org.apache.http.HttpResponse;
Import org.apache.http.client.HttpClient;
Import Org.apache.http.client.methods.HttpGet;
Import org.apache.http.impl.client.DefaultHttpClient;

Import Org.apache.http.util.EntityUtils;
Import android.app.Activity;
Import Android.app.ProgressDialog;
Import Android.graphics.Bitmap;
Import Android.graphics.BitmapFactory;
Import Android.os.Bundle;
Import Android.os.Handler;
Import Android.view.View;
Import Android.widget.Button;

Import Android.widget.ImageView;
 public class HandlerPostActivity2 extends activity {private Button btndown;
 Private ImageView Ivimage;
 private static String image_path = "Http://ww4.sinaimg.cn/bmiddle/786013a5jw1e7akotp4bcj20c80i3aao.jpg";
 Private ProgressDialog Dialog;
 A static Handler,handler recommendation is declared as a static private static Handler handler=new Handler ();
 @Override protected void OnCreate (Bundle savedinstancestate) {super.oncreate (savedinstancestate); Setcontentview (r.layout.asynctask_activity);
 Btndown = (Button) Findviewbyid (R.id.btndown);

 Ivimage = (ImageView) Findviewbyid (r.id.ivsinaimage);
 dialog = new ProgressDialog (this);
 Dialog.settitle ("hint");
 Dialog.setmessage ("Downloading, please later ...");
 
 Dialog.setcancelable (FALSE);
  Btndown.setonclicklistener (New View.onclicklistener () {@Override public void OnClick (View v) {//Open a child thread for downloading pictures
  New Thread (New Mythread ()). Start ();
  Display dialog box Dialog.show ();
 }
 }); public class Mythread implements Runnable {@Override public void run () {//download a picture httpclient httpclient = NE
  W defaulthttpclient ();
  HttpGet httpget = new HttpGet (image_path);
  HttpResponse HttpResponse = null;
  try {HttpResponse = Httpclient.execute (HttpGet); if (Httpresponse.getstatusline (). Getstatuscode () = = byte[] data = Entityutils.tobytearray (HttpResponse. GetE
   Ntity ());
   A Bitmap object is obtained, and in order for it to be accessible within post, it must be declared final final Bitmap Bmp=bitmapfactory.decodebytearray (data, 0, data.length); Handler.post (New RuNnable () {@Override public void run () {//UI Component ImageView Ivimage.setimagebitmap (BMP) in post;
   }
   });
  Hide dialog box Dialog.dismiss ();
  } catch (Exception e) {e.printstacktrace (); }
 }

 }
}

Effect Display:

Message

Handler if you use SendMessage to queue messages into message queues, you need to pass a message object, and in handler you need to override the Handlemessage () method to get the work line Cheng the message that is passed. This method runs on the UI thread. Let me introduce the message below.

Message is a final class, so it cannot be inherited. Message encapsulates messages that are passed in a thread, and if for general data, it provides a getdata () and SetData () method to get and set the data, where the manipulated data is a bundle object that provides a series of getxxx () and Setxxx () methods are used to pass key-value pairs of basic data types, which are simple to use for basic data types, and are not explained in detail here. For complex data types, such as the delivery of an object will be relatively complex. There are two methods in bundle that are specifically used to pass objects, but these two methods also have their own limitations and need to implement specific interfaces, of course, some of the Android self-contained classes have actually implemented one of these two interfaces and can be used directly. The method is as follows:

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 the object in the message, which is to use the obj attribute with the message itself to pass the value, it is an object type, so you can pass any type of object, the message comes with several attributes as follows:

int arg1: Parameter one, used to pass the uncomplicated data, the complex data uses SetData () to pass.

int arg2: Parameter two, which is used to pass uncomplicated data, and complex data is passed using SetData ().

Object obj: Passing an arbitrary object.

int WHAT: A defined message code that is typically used to set the flag of a message.

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

Since message is passed between threads, let's use a demo to explain how messages are used, or to download a demo of a picture from the Internet, and use the ImageView control to display it after downloading:

Package Com.bgxt.datatimepickerdemo;
Import Org.apache.http.HttpResponse;
Import org.apache.http.client.HttpClient;
Import Org.apache.http.client.methods.HttpGet;
Import org.apache.http.impl.client.DefaultHttpClient;

Import Org.apache.http.util.EntityUtils;
Import android.app.Activity;
Import Android.app.ProgressDialog;
Import Android.graphics.Bitmap;
Import Android.graphics.BitmapFactory;
Import Android.os.Bundle;
Import Android.os.Handler;
Import Android.os.Message;
Import Android.view.View;
Import Android.widget.Button;

Import Android.widget.ImageView;
 public class HandlerMessageActivity1 extends activity {private Button btndown;
 Private ImageView Ivimage;
 private static String image_path = "Http://ww4.sinaimg.cn/bmiddle/786013a5jw1e7akotp4bcj20c80i3aao.jpg";
 Private ProgressDialog Dialog;

 private static int is_finish = 1;
 @Override protected void OnCreate (Bundle savedinstancestate) {super.oncreate (savedinstancestate);

 Setcontentview (r.layout.asynctask_activity); BTndown = (Button) Findviewbyid (R.id.btndown);

 Ivimage = (ImageView) Findviewbyid (r.id.ivsinaimage);
 dialog = new ProgressDialog (this);
 Dialog.settitle ("hint Information");
 Dialog.setmessage ("Downloading, please later ...");

 Dialog.setcancelable (FALSE); Btndown.setonclicklistener (New View.onclicklistener () {@Override public void OnClick (View v) {New Thread (new myth
   Read ()). Start ();
  Dialog.show ();
 }
 }); Private Handler Handler = new Handler () {//Get message in Handler, override Handlemessage () method @Override public void Handlemessage (
  Message msg) {//To determine if the messaging code is 1 if (msg.what==is_finish) {byte[] Data= (byte[)) msg.obj;
  Bitmap bmp=bitmapfactory.decodebytearray (data, 0, data.length);
  Ivimage.setimagebitmap (BMP);
  Dialog.dismiss ();

 }
 }
 }; public class Mythread implements Runnable {@Override public void run () {httpclient httpclient = new Defaulthttpclie
  NT ();
  HttpGet httpget = new HttpGet (image_path);
  HttpResponse HttpResponse = null; try {HttpResponse = Httpclient.execute (httpget); if (Httpresponse.getstatusline (). Getstatuscode () = = byte[] data = Entityutils.tobytearray (HttpResponse. GetE
   Ntity ());
   Gets a Message object, sets the what to 1 message msg = Message.obtain ();
   Msg.obj = data;
   Msg.what = Is_finish;
  Send this message to the message Queue Handler.sendmessage (msg);
  } catch (Exception e) {e.printstacktrace (); }
 }
 }
}

Show Effect:

The Message.obtain () method has several overloaded methods, which can be divided into two categories, one without the need to pass the handler object, and for this kind of method, when the good message is filled, the Handler.sendmessage () method needs to be invoked to send the message to the message queue. The second class needs to pass a handler object that can send a message directly to the message queue using the Message.sendtotarget () method because there is a private handler type attribute Target in the Messages object, When the obtain method passes into a handler object, it assigns a value to the target property, which is actually inside or called the Target.sendmessage () method when the Sendtotarget () method is invoked.

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

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

Message Obtainmessage (): Gets a Message object.

Boolean SendMessage (): Sends a Message object to the queue and executes immediately after the UI thread has fetched the message.

Boolean sendmessagedelayed (): Sends a Message object to the queue and delays execution after the UI thread has fetched the message.

Boolean sendemptymessage (int what): Sends an empty message object to the queue and executes it immediately after the UI thread has fetched it.

Boolean sendemptymessagedelayed (int what,long delaymillis): Sends an empty message object to the queue and delays execution after the UI thread takes a message.

void Removemessage (): Removes an unresponsive message from the message queue.

Here's a demo of the various ways to send messages by using a small demo:

Package Com.bgxt.datatimepickerdemo;
Import android.app.Activity;
Import Android.os.Bundle;
Import Android.os.Handler;
Import Android.os.Message;
Import Android.view.View;
Import Android.widget.Button;

Import Android.widget.TextView;
 public class HandlerMessageActivity2 extends activity {private Button btn1, BTN2, Btn3, btn4,btn5;
 private static TextView tvmes; 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");
  else {tvmes.settext ("what=" + Msg.what + "," + msg.obj.toString ());
 }

 };

 }; @Override protected void OnCreate (Bundle savedinstancestate) {//TODO auto-generated Method stub super.oncreate (Savedi
 Nstancestate);
 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); Btn1.setonclicklistener (New View.onclicklistener () {@Override public void OnClick (View v) {//Use Message.obtain+han 
   Der.sendmessage () sends messages 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);
  }). Start ();

 }
 }); Btn2.setonclicklistener (New View.onclicklistener () {@Override public void OnClick (View v) {//Use Message.sendtotar
   Get sends messages new Thread (new Runnable () {@Override public void run () {msg = Message.obtain (handler);
   Msg.what = 2;
   Msg.obj = "Send Message using Message.sendtotarget";
   Msg.sendtotarget ();
  }). Start ();

 }
 }); Btn3.setonclicklistener (New View.onclicklistener () {//Send a delay message @Override public void OnClick (View v) {new Threa D (New RunnablE () {@Override public void run () {handler.sendemptymessage (3);
  }). Start ();

 }
 }); Btn4.setonclicklistener (New View.onclicklistener () {@Override public void OnClick (View v) {New Thread (new RUNNABL
   E () {@Override public void run () {msg = Message.obtain ();
   Msg.what = 4;
   Msg.obj = "Send delay message using message.obtain+hander.sendmessage ()";
   Handler.sendmessagedelayed (MSG, 3000);
  }). Start ();
 
 }
 }); Btn5.setonclicklistener (New View.onclicklistener () {//Send a deferred empty message @Override public void OnClick (View v) {new Thr
   EAD (New Runnable () {@Override public void run () {handler.sendemptymessagedelayed (5, 3000);
  }). Start ();
 }
 }); }
}

Effect Show

The above is to the Android Handler data collation, follow-up continue to supplement the relevant information, thank you for your support of this site!

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.