Some of the previous posts briefly described some of the common HTTP operations, which are almost all network requests made in the newly opened thread, and print out the obtained network data in the log. So, here's the problem! (er ~ Feel the next one is Blue Xiang has wood?) How to display the acquired network data on the UI interface? If you follow the example of a previous blog post and directly manipulate the network data fetched by the child thread in the main thread, you will find that the data returned from the server is not available to the child thread at all in the main thread. Because the network operation is a time-consuming operation, in order to not block the main thread and placed in the child thread, when the main thread in the code after the execution of the child thread does not necessarily get the data returned by the server. So, in order to solve this problem we usually add an asynchronous message mechanism to the HTTP operation, and simply encapsulate it for ease of operation, plus a callback mechanism.
This blog post to httpclient visit Baidu homepage For example, to the previous blog post HTTP operation further perfect.
First, recall the simplest steps or processes that use httpclient:
(The strURL here is "http://www.baidu.com", and STR is the data returned from the server.) )
Newnew httpget (strURL); HttpResponse response= Client.execute (request); if (Response.getstatusline (). Getstatuscode ()= = entityutils.tostring (response.getentity ());}
The following steps are based on these actions to achieve a simple encapsulation:
First, add the callback mechanism:
(If you're not familiar with callbacks, please refer to the Java callback mechanism parsing)
Public Interface httpcallback { void onsuccess (Object result); void onfailure (Exception result);}
Next, implement a request class:
This class has a total of three attributes:
Method is an object of type Requestmethod that is qualified with the enum type in the class, and is used to set the request mode.
The URL is the path to the network request.
The callback is the callback interface object that is used to pass data to the call when the data is fetched in the network request.
Public classRequest { PublicRequestmethod method; PublicString URL; PublicHttpcallback callback; PublicRequest (String URL, Requestmethod method) { This. method =method; This. url =URL; } PublicRequest (String url) { This. method =Requestmethod.get; This. url =URL; } Public enumRequestmethod {GET, POST, DELETE, PUT} Public voidSetcallback (Httpcallback callback) { This. Callback =callback; } Public voidExecute () {requsttask task=NewRequsttask ( This); Task.execute (); }}
As you can see from the code above, the two constructors of the class need to pass in the URL, where one constructor can set the request way and the other sets the default request mode get.
There is an execute () method in this class, in which the Requesttask class inherits from Asynctask, which is the function of making a network request in Requesttask.
The Requesttask code is as follows:
Public classRequsttaskextendsAsynctask<void, Integer, object> { PrivateRequest Requset; PublicRequsttask (Request requset) { This. Requset =Requset; } @Overrideprotected voidOnPreExecute () {//TODO auto-generated Method Stub Super. OnPreExecute (); } @OverrideprotectedObject doinbackground (Void ... params) {Try{HttpResponse response=Httpclientutils.execute (Requset); if(Requset.callback! =NULL) { //if the callback interface is further abstracted, its sub-abstract classes can handle data in multiple formats (e.g. JSON, XML, String, File), which can be more convenient//This is directly used to return data of type string if(Response.getstatusline (). Getstatuscode () = =HTTPSTATUS.SC_OK) { returnentityutils.tostring (Response.getentity ()); } return"Request Failed"; } Else { return NULL; } } Catch(Exception e) {returne; }} @Overrideprotected voidOnPostExecute (Object result) {if(Requset.callback! =NULL) { if(ResultinstanceofException) {requset.callback.onFailure ((Exception) result); } Else{requset.callback.onSuccess (result); } }} @Overrideprotected voidonprogressupdate (Integer ... values) {//TODO auto-generated Method Stub Super. Onprogressupdate (values); }}
The constructor of this class needs to pass a request object, according to the method property of this Request object to determine the requested mode, URL properties to determine the request path, according to the callback property to determine whether to pass the acquired network data to the calling interface.
In Doinbackground (), NULL is returned if the request object's callback property is null:
When the callback property of the request object is not NULL, the status code returned by the server (where response is the information returned by the server) is first fetched, and the response is successful if it equals 200 (that is, HTTPSTATUS.SC_OK). Call the GetEntity () method again to get to a httpentity instance, and then use the static method of entityutils.tostring () to convert the httpentity to a string and return. The returned data is passed into the OnPostExecute () method as a parameter.
if(Requset.callback! =NULL) { //if the callback interface is further abstracted, its sub-abstract classes can handle data in multiple formats (e.g. JSON, XML, String, File), which can be more convenient//This is directly used to return data of type string if(Response.getstatusline (). Getstatuscode () = =HTTPSTATUS.SC_OK) { returnentityutils.tostring (Response.getentity ()); } return"Request Failed"; } Else { return NULL; }
The callback property of the Request object in OnPostExecute () null does not return at all. Conversely, the result of Doinbackground () will be passed to the call of the callback interface:
if NULL { ifinstanceof Exception) { requset.callback.onFailure (Exception) result ); Else { requset.callback.onSuccess (result); } }
There is a code in Doinbackground ():
HttpResponse response = Httpclientutils.execute (Requset);
The httpclientutils here is actually a simple package with the following code:
Public classHttpclientutils { Public StaticHttpResponse Execute (Request requst)throwsException {Switch(requst.method) { CaseGET:returnget (Requst); } return NULL; } Private StaticHttpResponse Get (Request requst)throwsclientprotocolexception, IOException {HttpClient client=Newdefaulthttpclient (); HttpGet Get=NewHttpGet (Requst.url); HttpResponse Response=Client.execute (GET); returnresponse; }}
As you can see from the code, the Execute () and get () methods are both static types and the return type is HttpResponse. In the Execute () method, the method property of the incoming request object is used in conjunction with the switch statement to execute the corresponding network request, and returns information about the type of HttpResponse obtained from the server. This information is used directly in the Requsttask class.
This is the general process.
Finally, the use of the activity:
Public classMainactivityextendsActivity {PrivateButton btn; PrivateTextView TV; PrivateRequest request; @Overrideprotected voidonCreate (Bundle savedinstancestate) {Super. OnCreate (savedinstancestate); Setcontentview (R.layout.main); BTN=(Button) Findviewbyid (R.ID.BTN); TV=(TextView) Findviewbyid (r.id.tv); Request=NewRequest ("http://www.baidu.com", Requestmethod.get); Btn.setonclicklistener (NewOnclicklistener () {@Override Public voidOnClick (View v) {Try{request.setcallback (NewHttpcallback () {@Override Public voidonsuccess (Object result) {Tv.settext (String) result); } @Override Public voidonfailure (Exception result) {Tv.settext ("Request Failed"); } }); } Catch(Exception e) {//TODO auto-generated Catch blockE.printstacktrace (); } request.execute (); } }); }}
The activity layout file is as follows:
<?XML version= "1.0" encoding= "Utf-8"?><LinearLayoutxmlns:android= "Http://schemas.android.com/apk/res/android"Android:layout_width= "Match_parent"Android:layout_height= "Match_parent"android:orientation= "vertical" > <ButtonAndroid:id= "@+id/btn"Android:layout_width= "Wrap_content"Android:layout_height= "Wrap_content"Android:text= "Request" /> <ScrollViewAndroid:id= "@+id/sv"Android:layout_width= "Match_parent"Android:layout_height= "Wrap_content" > <TextViewAndroid:id= "@+id/tv"Android:layout_width= "Fill_parent"Android:layout_height= "Fill_parent" /> </ScrollView></LinearLayout>
View Code
To run the program, the effect is as follows:
Demo Download: http://download.csdn.net/detail/af74776/8066779
Android HTTP network programming (IV)