Android uses HTTP protocol to communicate with server
There are many articles on the Internet about HTTP communication on Android, but most of them give only fragments of implementation code, some considerations and how to design a reasonable class to handle all HTTP requests and return results, which are generally not mentioned. So, I made a summary of this and gave me a solution.
First, we need to clarify the HTTP communication process, Android currently provides two kinds of HTTP communication methods,HttpURLConnection和HttpClient,HttpURLConnection多用于发送或接收流式数据,因此比较适合上传/下载文件,HttpClient相对来讲更大更全能,但是速度相对也要慢一点。在此只介绍HttpClient的通信流程:
1. Create a HttpClient object that can be used to send different HTTP requests multiple times
2. Create HttpPost or HttpGet objects, set parameters, and each time an HTTP request is sent, an object is required
3. Using the Execute method of httpclient to send the request and wait for the result, the method will block the current thread until the result is returned or an exception is thrown.
4. Handle the results and exceptions accordingly
According to the above process, there are a few things to consider when designing a class:
1.HttpClient objects can be reused, so they can be used as static variables for classes
2.httppost/httpget objects are generally not reusable (you can reuse them every time you request a parameter), so you can create a method to initialize and set up some resources to upload to the server
3. Currently Android no longer supports initiating HTTP requests in the UI thread, and should not actually do so, because it blocks the UI thread. Therefore, a child thread is also required to initiate an HTTP request that executes the Execute method
4. Different requests correspond to different return results, and a certain degree of freedom is required for handling the returned results (generally parsing the json& update UI).
5. The simplest approach is to send a message to the UI thread as appropriate whenever an HTTP request is sent, a child thread is used to send a request, a result is received in a child thread, or an exception is thrown. Finally, the result parsing and UI update are done in the handler Handlemessage method of the UI thread. While this is simple, the UI thread and HTTP requests are highly coupled and the code is messy and ugly.
For some of these reasons, I designed a postrequest class to meet my HTTP communication needs. I only use the POST request, if you need a GET request, you can also change to write Getrequest
package com.handspeaker.network;import java.io.ioexception;import Java.io.unsupportedencodingexception;import java.net.uri;import java.net.urisyntaxexception;import java.util.concurrent.ExecutorService;import java.util.concurrent.Executors;import org.apache.http.httpresponse;import org.apache.http.client.clientprotocolexception;import org.apache.http.client.httpclient;import org.apache.http.client.methods.httppost;import org.apache.http.entity.stringentity;import org.apache.http.impl.client.defaulthttpclient;import org.apache.http.params.httpconnectionparams;import org.apache.http.params.httpparams;import org.apache.http.protocol.http;import org.apache.http.util.entityutils;import org.json.jsonobject; import android.app.activity;import android.content.context;import android.net.connectivitymanager;import android.os.handler;import android.util.log;/** * * for encapsulating & simplifying HTTP communication * */public class PostRequest implements Runnable { private static final int no_server_error= 1000; //Server Address public static final string url = "Fill your own url"; //some request types public final static String ADD = "/add"; public final static String UPDATE = "/update"; public final static string ping = "/ping"; //some parameters private static int connectiontimeout = 60000; private static int sockettimeout = 60000; //class static variable private static httpclIent httpclient=new defaulthttpclient (); private static Executorservice executorservice=executors.newcachedthreadpool (); private Static handler handler = new handler (); //variable private String strResult; private HttpPost httpPost; private HttpResponse httpResponse; private onreceivedatalistener onreceivedatalistener; private int statuscode; /** * constructors, initialize some variables that can be reused */ public postrequest () { strresult = null; httpresponse = null ; hTtppost = new httppost (); } /** * register to receive data listeners * @param Listener */ public void setonreceivedatalistener (Onreceivedatalistener listener) { onreceivedatalistener = listener; } /** * initialize httppost * based on different request types * @param requestType * Request type * @param nameValuePairs * parameters that need to be passed */ pUblic void inirequest (String requesttype, jsonobject jsonobject) { httppost.addheader ("Content-type", "Text/json"); httppost.addheader ("CharSet", "UTF-8"); httppost.addheader ("Cache-control", "No-cache"); httpparams httpparameters = httppost.getparams (); httpconnectionparams.setconnectiontimeout (httpparameters, connectiontimeout); httpconnectionparams.setsotimeout (httpparameters, sockettimeout); httppost.setparams (httpparameters); try { &Nbsp; httppost.seturi (New uri (URL + requestType) ); httppost.setentity (new Stringentity (jsonobject.tostring (), http. Utf_8)); } catch (urisyntaxexception e1) { e1.printstacktrace (); } catch (unsupportedencodingexception e) { e.printstacktrace (); } } /** * Open a new thread to send an HTTP request */ public void execute () { executorservice.execute (this); } /** * Detect network Status * * @return true is available else false */ public static boolean Checknetstate (activity activity) { connectivitymanager connmanager = (Connectivitymanager) activity .getsystemservice (Context.CONNECTIVITY _service); if (Connmanager.getactivenetworkinfo () != null) { return Connmanager.getactivenetworkinfo (). isavailable (); } return false; } /** * specific execution codes for sending HTTP requests */ @Override public void run () { httpResponse = null; try { Httpresponse = httpclient.execute (HttpPost); strresult = entityutils.tostring (Httpresponse.getentity ()); } catch (CLIENTPROTOCOLEXCEPTION E1) { strResult = null; &nbSp; e1.printstacktrace (); } catch ( IOEXCEPTION E1) { strresult = null; e1.printstacktrace () ; } finally { if (httpresponse != null) { statusCode = Httpresponse.getstatusline (). Getstatuscode (); } else { statuscode=no_server_error; } if (onreceivedatalistener!=null) { //Add the Onreceivedata method of the registered listener to the message queue to execute handler.post (new runnable () { @Override public void run () { Onreceivedatalistener.onreceivedata (StRresult, statuscode); } }); } } } /** * listener for receiving and processing HTTP request Results * */ public interface OnReceiveDataListener { /** * the callback function for receiving the result data * from post request, and further processing will be done here * @param strResult the result in string style. * @param statuscode the status of the post */ public abstract void onreceivedata (string strresult,int StatusCode); }}
The code uses the Observer pattern, and any class that needs to receive the result of the HTTP request implements an abstract method of the Onreceivedatalistener interface, while the Postrequest instance calls the Setonreceivedatalistener method, Register the Listener. The complete invocation steps are as follows:
1. Create the Postrequest object, implement the Onreceivedata interface, write your own Onreceivedata method
2. Registering listeners
3. Call Postrequest's Inirequest method to initialize the request
4. Invoke the Execute method of Postrequest
Possible improvements:
1. If you need more than one observer, you can register only a single listener to register multiple listeners and maintain a list of listeners.
2. Inirequest and execute can be merged if the requirements are simple and you want the invocation process to be more concise
Android uses HTTP protocol to communicate with server