Objective
Android since 4.0, all network access requires asynchronous process operations. Its own asynchronous class has Asynctask,handler, and can declare thread and so on. When it comes to multiple processes, it must be mentioned that there is no direct communication between threads and threads, the data of the UI thread is protected, and the actions that cannot be performed on the UI thread require other means of transmitting the data, and this article uses the handler SendMessage approach.
Body
This article involves hander and thread, first introduce hander.
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:
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 (Vi EW v) {//New start a sub-thread of Runnable (new) {@Over Ride public void Run () {//Tvmessage.settext ("..."); The above 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//using post to modify the UI component Tvmessage's Text property Handler.post (New Runnable () {@Override public void Run () {Tvmessage.settext ("Use Handler.post to send a piece of execution to the message queue in a worker thread, executed in the main thread. "); } }); }}). Start (); } }); Btnmes2.setonclicklistener (New View.onclicklistener () {@Override public void OnClick (Vi EW v) {New Thread (new Runnable () {@Override Pub LIC void Run () {//Modify the Text property value of the UI component Tvmessage using the Postdelayed method//and Delay 3S execution handler.postdelayed (new Runnable () { @Override public void Run () {Tvmessage.settext ("use HANDLER.P Ostdelayed sends a piece of execution to the message queue in a worker thread, delaying 3S execution in the main thread. "); }}, 3000); }}). Start (); } }); }}
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 it does with post.
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 a pass-through between the threads, the use of a demo to explain it, or the usual data received from WEBAPI on the Internet, is displayed using the ListView control after downloading:
Package Com.example.myrixin;import Java.util.arraylist;import Java.util.hashmap;import java.util.List;import Java.util.map;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 Org.json.jsonarray;import Org.json.jsonexception;import Org.json.jsonobject;import Android.os.bundle;import Android.os.handler;import Android.os.Message;import Android.app.activity;import Android.app.progressdialog;import Android.content.intent;import Android.util.Log; Import Android.view.menu;import Android.view.view;import Android.widget.abslistview;import Android.widget.abslistview.onscrolllistener;import Android.widget.adapterview;import Android.widget.adapterview.onitemclicklistener;import Android.widget.arrayadapter;import Android.widget.ListView ; Import Android.widget.toast;public class Mainactivity extends Activity implements OnitemclicklisTener, Onscrolllistener {public ListView listview;private static int is_finish = 1;private ProgressDialog dialog;private s Tatic string Url= "http://10.185.210.173:8008/api/products";p rivate arrayadapter<list<map<string, string >>>arr_adapter; @Override protected void OnCreate (Bundle savedinstancestate) {super.oncreate (savedinstancestate); Setcontentview (R.layout.activity_main); Instantiate a ListView listview= (ListView) Findviewbyid (R.ID.SJLB); dialog = new ProgressDialog (this); Dialog.settitle ("hint message"); Dialog.setmessage ("Downloading, please later ..."); Dialog.setcancelable (FALSE); New Thread (New MyThread ()). Start ();d ialog.show (); Adapter//arr_adapter=new arrayadapter (null, 0, list);////joins Listview//listview.setadapter (Arr_adapter); Listview.setonitemclicklistener (this);//Single entry click on Listener Listview.setonscrolllistener (this);//scroll Change listener} PR Ivate Handler Handler = new Handler () {map<String, string> map = null; list<map<string, string>> list = new arraylist<map<string, string>> ();//Get messages in handler, Override Handlemessage () method @overridepublic void Handlemessage (Message msg) {//To determine if the message code is 1if (msg.what = = is_finish) {// Text.settext (msg.tostring); list = JX (msg.tostring ());//try {////intercept API the data returned by the message has been added to the data in the text//int begin= Msg.tostring (). IndexOf ("[");//int end=msg.tostring (). IndexOf ("]");//string request=msg.tostring (). SUBSTRING ( Begin, End+1);////jsonarray Jsonarray = new Jsonarray (request),//for (int i = 0; i < jsonarray.length (); i++) {//jsonob Ject item = jsonarray.getjsonobject (i); Each record is made up of several object objects//int id = item.getint ("id"); Gets the value of the object {"Id": 1, "name": "Tomato Soup", "Category": "Groceries", "price": 1.0}//string name = item.getstring ("name"); /string categroy=item.getstring ("Category");//string price = Item.getstring ("price");////map = new hashmap<string, String> (); Store in Map//map.put ("id", ID + ""),//map.put ("name", name),//map.put ("CAtegory ", Categroy);//map.put (" Price ", price);//list.add (map);//}//for (map<string, string> list2:list) {// String id = list2.get ("id");//string name = List2.get ("name");//LOG.I ("info", "ID:" + id + "| Name: "+ Name"),//}//} catch (Jsonexception e) {////TODO auto-generated catch Block//e.printstacktrace ();//}//Adapter Arr_ Adapter=new Arrayadapter (Mainactivity.this, Android. R.layout.simple_expandable_list_item_1, list);//Join Listviewlistview.setadapter (arr_adapter);d Ialog.dismiss ();}}; public class MyThread implements Runnable {@Overridepublic void run () {HttpClient HttpClient = new Defaulthttpclient (); HttpGet httpget = new HttpGet (URL); HttpResponse HttpResponse = null;try {HttpResponse = Httpclient.execute (HttpGet); if (Httpresponse.getstatusline (). Getstatuscode () = = () {String temp = entityutils.tostring (httpresponse.getentity ());//Gets a Message object, Set what is 1Message msg = Message.obtain (); msg.obj = Temp;msg.what = is_finish;//Send this message to the message Queue Handler.sendmessage (msg);}} catch (Exception e) {E.printstacktrace ();}}} /* Parse JSON data */public list<map<string, string>> jx (String msg) {map<string, string> Map = null; list<map<string, string>> list = new arraylist<map<string, string>> (); try {//intercept the data returned by the API The data sent by the message is added to the text of the message int begin=msg.tostring (). IndexOf ("["); int end=msg.tostring (). IndexOf ("]"); String request=msg.tostring (). substring (begin, end+1); Jsonarray Jsonarray = new Jsonarray (request), for (int i = 0; i < jsonarray.length (); i++) {Jsonobject item = Jsonarray. Getjsonobject (i); Each record is also composed of several object objects int id = item.getint ("id"); Gets the value of the object {"Id": 1, "name": "Tomato Soup", "Category": "Groceries", "price": 1.0}string name = item.getstring ("name"); String categroy=item.getstring ("Category"); String Price = item.getstring ("price"); map = new hashmap<string, string> (); Deposit into Map map.put ("id", ID + ""), Map.put ("name", name), Map.put ("Category", Categroy); Map.put ("Price", price); List.add (map);} For (map<string, string> list2:list) {String id = list2.get ("id"); String name = List2.get ("name"); LOG.I ("info", "ID:" + id + "| Name: "+ Name";}} catch (Jsonexception e) {//TODO auto-generated catch Blocke.printstacktrace ();} return list;} /* * Custom menu Bar * @see android.app.activity#oncreateoptionsmenu (android.view.Menu) */@Override public boolean Oncreateo Ptionsmenu (Menu menu) {//Inflate the menu; This adds items to the action bar if it is present. Getmenuinflater (). Inflate (R.menu.main, menu); return true; } }
The content in XML
<relativelayout xmlns:android= "http://schemas.android.com/apk/res/android" xmlns:tools= "http// Schemas.android.com/tools " android:layout_width=" match_parent " android:layout_height=" Match_parent " android:paddingbottom= "@dimen/activity_vertical_margin" android:paddingleft= "@dimen/activity_ Horizontal_margin " android:paddingright=" @dimen/activity_horizontal_margin " android:paddingtop=" @dimen /activity_vertical_margin " tools:context=". Mainactivity "> <listview android:id=" @+id/sjlb " android:layout_width=" Match_parent " android:layout_height= "Wrap_content" android:layout_centerhorizontal= "true" android:layout_ Centervertical= "true" > </ListView></RelativeLayout>
Run:
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.
Interested in the message can be consulted: http://www.cnblogs.com/shirley-1019/p/3557800.html
A lot of the knowledge of this article is the reference Zeboven, I only have to revise the part which I need
Android Access Webapi, and retrieve data