(the original source for this blog: http://www.cnblogs.com/linguanh/)

Preface:

GitHub has been open source, I hope you can work with me to improve it, there are certainly a lot of shortcomings, but overall, it is good.

Why write this? Here’s why:

Before this, there are many good network request frameworks known, such as Android-Async-HTTP, okHttp, etc., the underlying implementation of this kind of excellent framework is also based on the system thread pool and httpClient or HttpUrlConnection, I’m sure a lot of developers use these frameworks without knowing about them themselves.

As a qualified Android developer, I think I must be able to use the API provided by the SDK of the system to realize functions by myself. I do not suggest not using frameworks, but only using existing resources to realize required functions independently, without relying on Baidu and completely cutting off the Internet, before using these frameworks. This way you won’t become a “framework engineer” and you’ll be confident when you go into an interview!

This article is not just about Java/Android; the same advice can be applied to other languages.

  

The preparatory work

1. Understand and use common development patterns such as singleton, observer, simple factory, etc. To develop frameworks, the use of development patterns is essential, both in terms of code decoupling and in terms of memory optimization. The former has ImageLoader, which uses a singleton pattern of dual dependent types, including Android’s familiar event mechanism, which is the observer pattern, and the adapter pattern.

2, understand and use some development principles, such as interface separation, a large project without a few interfaces, and interfaces can bring us great convenience.

3, understand and learn to use threads and optimize the network request class framework, we know that Android is not in the main thread (also known as UI thread) for network operations, so our framework must use child threads, which requires you to master the knowledge of thread class. For example, simple Thread + Runnable + Handler combinations, more heavyweight AsyncTask.

4. To deal with high concurrency, multi-threaded operations are often carried out in an application, and the Memory allocation of a Java virtual machine for a thread is about 1M, depending on the task it performs. Thread pools are the first word that comes to mind, so you need to understand them and learn to use them flexibly.

5. Understand the structure of Tcp/Udp packets and the differences in Post modes. Remember there’s a lot of requirements that you have to know about TCP? If you see a requirement like this and say it in your head, it means you haven’t actually used it, which I’ll note in my code comments later.

6, others (e.g. a compiler….)

 

This class introduces

Don’t say framework, say class, ha ha, don’t be so lofty. Following on from the points mentioned in the preparation above, I’ll explain how they are used in this Http utility class.

1, on the development mode, I used the singleton pattern of the static inner class, so there are two advantages, one is to guarantee the class don’t want to hungry mode when not in use the same memory in the beginning, but a slob model, and the static inner class is in order to solve the problem of thread safety, it is only in the use of virtual machines in the JVM class loading step 5 when initialized, Clinit <> in this step is thread-safe and does not cause additional problems, synchronization failures, or cost resources by using the synchronized keyword.

public static LghHttp getInstance(){
      return LghHttpStatic.singleLghHttp;
}

private static class LghHttpStatic{
      private static LghHttp singleLghHttp = new LghHttp();
}Copy the code

 

2. In terms of development principles, interface separation is adopted, which is mainly reflected in data processing.

Private interface LghHttpBaseListenr{void onFailed(int type); / / private interface LghHttpBaseListenr{void onFailed(int type); // void onUrlFailed(); // void onTimeOut(); // void onProtocolFailed(); // void onEncodingFailed(); // void onIoFailed(); } public interface LghHttpGlobleListener extends LghHttpBaseListenr{void onSuccess(int);} public interface LghHttpGlobleListener extends LghHttpBaseListenr{void onSuccess(int) requestCode,String response); } /** Public interface LghHttpSingleListener extends LghHttpBaseListenr{void onSuccess(String); /** Public interface LghHttpSingleListener extends LghHttpBaseListenr{void onSuccess(String) response); }Copy the code

 

3. For threads and concurrency, a thread pool of type newFixdThreadPool is used. If you want to replace it with newCacheThreadPool, it is recommended to replace it with newFixdThreadPool. There are several resident threads throughout the APP, so you don’t need to repeatedly new your APP and then destroy it when you exit. NewCacheThreadPool will automatically reclaim the thread after the task is done. It will free up thread memory for you, so there are no resident threads.


1 public synchronized void init(){3 this.threadpool = (ThreadPoolExecutor) Executors.newFixedThreadPool(3); 4 this.handler = new Handler(){ 5 @Override 6 public void handleMessage(Message msg) { 7 super.handleMessage(msg); 8 9 HttpDataBean bean = (HttpDataBean) msg.obj; 10 LghHttpBaseListenr tempListener; 11 if(GloblelghHttpListeners! =null){/** Take global priority */ 12 tempListener = GloblelghHttpListeners; 13 }else if(bean.getListeners()! =null){ 14 tempListener = bean.getListeners(); 15 }else{ 16 return; 17 } 18 switch (msg.what){ 19 case Success: 20 if(GloblelghHttpListeners! = null) {/ * * to global priority * / 21 GloblelghHttpListeners onSuccess (MSG. Arg1, bean. The method getResponse ()); 22 }else{ 23 bean.getListeners().onSuccess(bean.getResponse()); 24 } 25 break; 26 case UrlFailed: 27 tempListener.onFailed(UrlFailed); 28 break; 29 case TimeOut: 30 tempListener.onFailed(TimeOut); 31 break; 32 case ProtocolFailed: 33 tempListener.onFailed(ProtocolFailed); 34 break; 35 case EncodingFailed: 36 tempListener.onFailed(EncodingFailed); 37 break; 38 case IOFailed: 39 tempListener.onFailed(IOFailed); 40 break; 41 default: 42 /** this is not possible to enter, also as a leave to your own interface */ 43 break; 44} 45} 46}; 47}Copy the code

4. In terms of functions, three common operations are provided:

1) Get request operation


Public void doGet(final String URL){3 doGet(-1, url, null); 4 } 5 6 public void doGet(final int requestCode,final String url){ 7 doGet(requestCode, url, null); 8 } 9 10 public void doGet( 11 final int requestCode, 12 final String url, 13 final LghHttpSingleListener lghHttpListeners) 14 { 15 Runnable runnable = new Runnable() { 16 @Override 17 public void run() { 18 get(requestCode, url, lghHttpListeners); 19}}; 21 if(threadPool ! = null){ 22 threadPool.execute(runnable); 23 }else{ 24 Log.d(TAG,"do get threadPool is null"); 25 } 26 } 27 28 private void get(int requestCode,String url,LghHttpSingleListener lghHttpListener){ 29 try { 30 HttpURLConnection httpURLConnection = getHttpUrlConnection(url,"GET"); 31 httpURLConnection.setUseCaches(false); 32 sendMessage(Success,requestCode, commonGetResult(httpURLConnection,lghHttpListener)); 33 } catch (MalformedURLException e) { 34 dealWithException(e,lghHttpListener); 35 } catch (IOException e) { 36 dealWithException(e,lghHttpListener); 37}} 38Copy the code

2) Post request operation


2 public void doPost(String url){3 doPost(-1, url); 4 } 5 6 public void doPost(int requestCode,String url){ 7 doPost(requestCode, url, null, null); 8 } 9 10 public void doPost(int requestCode,String url,LghHttpSingleListener listener){ 11 doPost(requestCode, url, null, null,listener); 12 } 13 14 public void doPost(int requestCode,String url,String[] keys,String[] values){ 15 doPost(requestCode, url, keys, values, null); 16 } 17 18 public void doPost( 19 final int requestCode, 20 final String url, 21 final String[] keys, 22 final String[] values, 23 final LghHttpSingleListener listener 24 ){ 25 Runnable runnable = new Runnable() { 26 @Override 27 public void run() { 28 post(requestCode, url,keys,values, listener); 29}} 30; 31 if(threadPool ! = null){ 32 threadPool.execute(runnable); 33 }else{ 34 Log.d(TAG,"do post threadPool is null"); 38 /** Uses the first post protocol, application/x-www-form-urlencoded */ 39 private void post( 40 int requestCode, 41 String url, 42 String[] keys, 43 String[] values, 44 LghHttpSingleListener listener 45 ){ 46 if(url==null){ 47 return; 48 } 49 try{ 50 HttpURLConnection httpURLConnection = getHttpUrlConnection(url,"POST"); 51 httpURLConnection.setDoOutput(true); / * * * / post necessary 52 httpURLConnection setUseCaches (false); 53 54 if(keys! =null && values! =null){ 55 OutputStream outputStream = httpURLConnection.getOutputStream(); 56 commonCombinePostText(keys,values,outputStream); 57 outputStream.flush(); 58 outputStream.close(); 59 } 60 sendMessage(Success,requestCode, commonGetResult(httpURLConnection,listener)); 61 }catch (MalformedURLException e){ 62 dealWithException(e,listener); 63 } catch (SocketTimeoutException e){ 64 dealWithException(e,listener); 65 } catch (ProtocolException e) { 66 dealWithException(e,listener); 67 } catch (UnsupportedEncodingException e) { 68 dealWithException(e,listener); 69 } catch (IOException e) { 70 dealWithException(e,listener); 72 71}}Copy the code

3) upload picture operation, some knowledge of Tcp packets, useful here.


Public void doUpLoadPic(3 String url, 4 String picName, 5 String streamName, 6 Bitmap bit 7 ){ 8 doUpLoadPic(-1, url, null, null, picName, streamName, bit, null); 9 } 10 11 public void doUpLoadPic( 12 int requestCode, 13 String url, 14 String picName, 15 String streamName, 16 Bitmap bit 17 ){ 18 doUpLoadPic(requestCode, url, null, null, picName, streamName, bit, null); 19 } 20 21 public void doUpLoadPic( 22 int requestCode, 23 String url, 24 String picName, 25 String streamName, 26 Bitmap bit, 27 LghHttpSingleListener listener 28 ){ 29 doUpLoadPic(requestCode, url, null, null, picName, streamName, bit, listener); 30 } 31 32 public void doUpLoadPic( 33 int requestCode, 34 String url, 35 String[] keys, 36 String[] values, 37 String picName, 38 String streamName, 39 Bitmap bit 40 ){ 41 doUpLoadPic(requestCode, url, keys, values, picName, streamName, bit, null); 42 } 43 44 public void doUpLoadPic( 45 final int requestCode, 46 final String url, 47 final String[] keys, 48 final String[] values, 49 final String picName, 50 final String streamName, 51 final Bitmap bit, 52 final LghHttpSingleListener listener 53 ){ 54 Runnable runnable = new Runnable() { 55 @Override 56 public void run() { 57 UpLoadPic(requestCode, url, keys, values, picName, streamName, bit, listener); 58}} 59; 60 if(threadPool ! = null){ 61 threadPool.execute(runnable); 62 }else{ 63 Log.d(TAG,"do post threadPool is null"); 64} 65} 66 67 /** 68 * This function is used to upload pictures 69 * post two packet formats: 70 * 1, application/x-www-form-urlencoded; Used to upload text 71 * 2, multipart/form-data; Binary transmission, in addition to text, can also be used to transfer files, such as pictures! 72 * 3, multipart/form-data; Boundary 73 * 4 must be delimited. At the end of the HTTP post request, there needs to be a boundary, but it should be preceded by -- : -- delimiter -- 74 * parameters: 75 * url 76 * picName the name of the image 77 * streamName The name of the fluid value 78 * $_FILES['streamName']['picName'] 79 **/ 80 private void UpLoadPic( 81 int requestCode, 82 String url, 83 String[] keys, 84 String[] values, 85 String picName, 86 String streamName, 87 Bitmap bit, 88 LghHttpSingleListener listener 89 ){ 90 String twoHyphens = "--"; /** must be 2 lines */ 91 String boundary = "******"; /** Can be custom */ 92 try{93 HttpURLConnection HttpURLConnection = getHttpUrlConnection(url,"POST"); 94 httpURLConnection.setUseCaches(false); 95 httpURLConnection.setDoOutput(true); 96 httpURLConnection.setChunkedStreamingMode(1024 * 256); / a transmission block size * * * / 97 / * * data -- -- -- -- -- -- -- - -- -- -- -- -- -- -- -- in baotou format assembly * / 98 httpURLConnection. SetRequestProperty (" Connection ", "Keep Alive -");  99 httpURLConnection.setRequestProperty("Content-Type","multipart/form-data; boundary="+boundary); 100 / * * data -- -- -- -- -- -- -- -- inclusions -- -- -- -- -- -- -- -- format assembly * / 101 DataOutputStream body = new DataOutputStream(httpURLConnection.getOutputStream()); 102 /** 登 记 +boundary+"\r\n"); 103 Body. WriteBytes (two登 记 +boundary+"\r\n"); */ 104 body. WriteBytes (105 "Content-disposition :form-data;" + 106 "name=\"" + streamName + "\";" + 107 "filename=\"" + picName + "\"" + "\r\n" 108 ); 109 /** Write text data body */ 110 body.writeBytes("\r\n"); 111 if(keys! =null && values! =null){ 112 body.writeBytes(twoHyphens+boundary+"\r\n"); 113 body.writeBytes("Content-Disposition:form-data;" ); 114 commonCombinePostText(keys,values,body); 115 body.writeBytes("\r\n"); 116} 117 / * * -- -- -- -- -- -- -- the following start to write the image binary -- -- -- -- -- - * / 118 / here is first compressed * / 119 * * int compress = 100; 120 ByteArrayOutputStream baos = new ByteArrayOutputStream(); 121 bit.compress(Bitmap.CompressFormat.JPEG, compress, baos); 122 if(IsOpenCompress){ 123 while (baos.toByteArray().length / 1024 > CompressLimit) { 124 baos.reset(); 125 compress -= 10; 126 if(compress==0){ 127 bit.compress(Bitmap.CompressFormat.JPEG, compress, baos); 128 break; 129 } 130 bit.compress(Bitmap.CompressFormat.JPEG, compress, baos); InputStream picStream = new ByteArrayInputStream(baos.tobytearray ()); 135 byte[] buffer = new byte[10*1024]; 136 int count; 137 while((count = picStream.read(buffer))! =-1){ 138 body.write(buffer,0,count); 139 } 140 picStream.close(); 141 body.writeBytes("\r\n"); 142 body.writeBytes(twoHyphens + boundary + twoHyphens +"\r\n"); 143 body.flush(); 144 / write * * * / 145 sendMessage (Success, requestCode commonGetResult (httpURLConnection, listener)); 146 body.close(); 147 }catch (MalformedURLException e){ 148 dealWithException(e,listener); 149 } catch (SocketTimeoutException e){ 150 dealWithException(e,listener); 151 } catch (ProtocolException e) { 152 dealWithException(e,listener); 153 } catch (UnsupportedEncodingException e) { 154 dealWithException(e,listener); 155 } catch (IOException e) { 156 dealWithException(e,listener); 158 157}}Copy the code

 

5. Advantages:

1) Absolute lightweight, can improve APK volume optimization, without relying on other third party libraries

2) Memory management can be assured

3) Request speed is pure system HttpUrlConnection, without too many code fragments

6. Classification can be further decoupled. In order to facilitate my own use, I wrote it in one, which can be divided into:

1) Public parts


1 /** Public part, */ 2 Private void dealWithException(3 Exception e, 4 LghHttpSingleListener lghHttpListeners) 5 { 6 HttpDataBean bean = new HttpDataBean(); 7 bean.setListeners(lghHttpListeners); 8 if(e instanceof MalformedURLException){9 log.d (TAG, "error "+ e.tostring ()); 10 sendMessage(UrlFailed,bean); 11}else if(e instanceof SocketTimeoutException){12 log.d (TAG, "connection timeout "+ e.tostring ()); 13 sendMessage(TimeOut,bean); 14}else if(e instanceof ProtocolException){15 log. d(TAG, "ProtocolException" + e.tostring ()); 16 sendMessage(ProtocolFailed, bean); 17} else if (e instanceof UnsupportedEncodingException) {18 the d (TAG, "encoding type exception" + e. oString ()); 19 sendMessage(EncodingFailed, bean); 20}else if(e instanceof IOException){21 log.d (TAG, "IO exception" + e.tostring ()); 22 sendMessage(IOFailed,bean); 23} 24} 25 26 /** Get an HttpUrlConnection, Merge some common parts */ 27 Private static HttpURLConnection getHttpUrlConnection 28 (String URL,String requestWay) throws IOException { 29 Log.d(TAG,"url is "+url); 30 URL mRrl = new URL(url); 31 HttpURLConnection httpURLConnection = (HttpURLConnection) mRrl.openConnection(); 32 httpURLConnection.setRequestMethod(requestWay); 33 httpURLConnection.setRequestProperty("Charset", "UTF-8"); 34 httpURLConnection.setConnectTimeout(5 * 1000); 35 return httpURLConnection; 39 private HttpDataBean commonGetResult(40 HttpURLConnection HttpURLConnection, 41 LghHttpSingleListener listener 42 ) throws IOException { 43 if(httpURLConnection==null){ 44 return null; 45 } 46 BufferedReader br = new BufferedReader 47 ( 48 new InputStreamReader(httpURLConnection.getInputStream(),"UTF-8"), 49 8*1024 50 ); 51 StringBuffer resultBuffer = new StringBuffer(""); 52 String line; 53 while ((line = br.readLine())! =null){ 54 resultBuffer.append(line); 55 } 56 HttpDataBean bean = new HttpDataBean(); 57 bean.setResponse(resultBuffer.toString()); 58 bean.setListeners(listener); 59 br.close(); 60 return bean; 61} 62 62 /** private OutputStream commonCombinePostText(65 String[] keys, 66 String[] values, 67 OutputStream outputStream) throws IOException 68 { 69 StringBuffer requestStr = new StringBuffer(); 70 int keysLength = keys.length; 71 for(int i=0; i<keysLength; i++){ 72 requestStr.append(keys[i]+"="+values[i]+"&"); 73 } 74 outputStream.write(requestStr.toString().getBytes()); 75 return outputStream; 76}Copy the code

2) Data


1 /** 2 * LghHttp base data class 3 * as the data seed passed by the handler, 4 * */ 5 Private Class HttpDataBean implements Serializable{6 7 private String Response; 8 private LghHttpSingleListener listeners; 9 10 public void setResponse(String response){ 11 this.response = response; 12 } 13 14 public void setListeners(LghHttpSingleListener listeners){ 15 this.listeners = listeners; 16 } 17 18 public String getResponse(){ 19 return this.response; 20 } 21 22 public LghHttpSingleListener getListeners(){ 23 return this.listeners; 25 24}}Copy the code

3) Request core

7. Expand and add the video uploading part.

 

Complete code:

The above nested explanation is split, and the complete one is provided here.

 

  1 package com.lghsaleimage;
  2 
  3 import android.graphics.Bitmap;
  4 import android.os.Handler;
  5 import android.os.Message;
  6 import android.util.Log;
  7 
  8 import java.io.BufferedReader;
  9 import java.io.ByteArrayInputStream;
 10 import java.io.ByteArrayOutputStream;
 11 import java.io.DataOutputStream;
 12 import java.io.IOException;
 13 import java.io.InputStream;
 14 import java.io.InputStreamReader;
 15 import java.io.OutputStream;
 16 import java.io.Serializable;
 17 import java.io.UnsupportedEncodingException;
 18 import java.net.HttpURLConnection;
 19 import java.net.MalformedURLException;
 20 import java.net.ProtocolException;
 21 import java.net.SocketTimeoutException;
 22 import java.net.URL;
 23 import java.util.concurrent.Executors;
 24 import java.util.concurrent.ThreadPoolExecutor;
 25 
 26 /**
 27  * Created by 林冠宏(指尖下的幽灵) on 2016/8/11.
 28  *
 29  * Blog : http://www.cnblogs.com/linguanh/;
 30  *
 31  * Name : http 工具类
 32  *
 33  * 前言:
 34  *     希望大家能够和我一起来完善它,该类肯定有很多不足的,但总体来说,还是不错的。
 35  *
 36  * 下面是简介和拓展:
 37  *
 38  *     1, 考虑到网络请求必不可少,采用了静态内部类单例模式
 39  *
 40  *     2, 采用 newFixedThreadPool 线程池来管理并发线程,
 41  *        如果要替换,建议使用 newCacheThreadPool
 42  *
 43  *     3, 功能方面提供三种常见操作:
 44  *           1)Get请求
 45  *           2)Post请求
 46  *           3)图片上传
 47  *     4, 优点:
 48  *           1) 绝对的轻量级,可以提升 APK 体积优化
 49  *           2)内存管理方面可以放心
 50  *           3)请求速度方法是纯系统的 HttpUrlConnection 请求,
 51  *              没有过多的代码片段
 52  *
 53  *     5,可以进一步解耦拆分类,分为:
 54  *           1)公共部分
 55  *           2)数据部分
 56  *           3)请求核心部分
 57  *
 58  *     6, 加入视频上传部分
 59  *
 60  */
 61 
 62 public class LghHttp {
 63 
 64     private final static String TAG = "zzzzz";
 65 
 66     public final static int Success = 0x10;
 67     public final static int UrlFailed = 0x11;
 68     public final static int TimeOut = 0x12;
 69     public final static int ProtocolFailed = 0x13;
 70     public final static int EncodingFailed = 0x14;
 71     public final static int IOFailed = 0x15;
 72 
 73     private final static boolean IsOpenCompress = true;/** 是否开启压缩 */
 74     private final static int CompressLimit = 500;      /** 压缩级别,单位是 K */
 75 
 76     private ThreadPoolExecutor threadPool;
 77     private Handler handler;
 78     /**
 79      * 全局回调接口 GloblelghHttpListeners
 80      * 注意:
 81      *     个人建议,如果请求页面多的,那就不要使用全局接口。尽量采用singleInterface
 82      *     否则,你需要在用户层页面的每次onResume重新设置
 83      * */
 84     private LghHttpGlobleListener GloblelghHttpListeners;
 85 
 86     public static LghHttp getInstance(){
 87         return LghHttpStatic.singleLghHttp;
 88     }
 89 
 90     private static class LghHttpStatic{
 91         private static LghHttp singleLghHttp = new LghHttp();
 92     }
 93 
 94     /** 销毁,内存释放善后操作 */
 95     public void destroy(){
 96         if(threadPool!=null){
 97             if(!threadPool.isShutdown()){
 98                 threadPool.shutdown();
 99                 threadPool = null;
100             }
101         }
102         if(handler!=null){
103             handler.removeCallbacksAndMessages(null);
104             handler = null;
105         }
106         if(GloblelghHttpListeners!=null){
107             GloblelghHttpListeners = null;
108         }
109         LghHttpStatic.singleLghHttp = null;
110     }
111 
112     public void setGloblelghHttpListeners(LghHttpGlobleListener GloblelghHttpListeners){
113         this.GloblelghHttpListeners = GloblelghHttpListeners;
114     }
115 
116     /**
117      * LghHttp 基础数据类
118      * 作为 handler 传递的数据种子,只在成功时传递
119      * */
120     private class HttpDataBean implements Serializable{
121 
122         private String response;
123         private LghHttpSingleListener listeners;
124 
125         public void setResponse(String response){
126             this.response = response;
127         }
128 
129         public void setListeners(LghHttpSingleListener listeners){
130             this.listeners = listeners;
131         }
132 
133         public String getResponse(){
134             return this.response;
135         }
136 
137         public LghHttpSingleListener getListeners(){
138             return this.listeners;
139         }
140     }
141 
142     /** 初始化函数 */
143     public synchronized void init(){
144         this.threadPool = (ThreadPoolExecutor) Executors.newFixedThreadPool(3);
145         this.handler = new Handler(){
146             @Override
147             public void handleMessage(Message msg) {
148                 super.handleMessage(msg);
149 
150                 HttpDataBean bean = (HttpDataBean) msg.obj;
151                 LghHttpBaseListenr tempListener;
152                 if(GloblelghHttpListeners!=null){ /** 以全局的优先 */
153                     tempListener = GloblelghHttpListeners;
154                 }else if(bean.getListeners()!=null){
155                     tempListener = bean.getListeners();
156                 }else{
157                     return;
158                 }
159                 switch (msg.what){
160                     case Success:
161                         if(GloblelghHttpListeners!=null){ /** 以全局的优先 */
162                             GloblelghHttpListeners.onSuccess(msg.arg1,bean.getResponse());
163                         }else{
164                             bean.getListeners().onSuccess(bean.getResponse());
165                         }
166                         break;
167                     case UrlFailed:
168                         tempListener.onFailed(UrlFailed);
169                         break;
170                     case TimeOut:
171                         tempListener.onFailed(TimeOut);
172                         break;
173                     case ProtocolFailed:
174                         tempListener.onFailed(ProtocolFailed);
175                         break;
176                     case EncodingFailed:
177                         tempListener.onFailed(EncodingFailed);
178                         break;
179                     case IOFailed:
180                         tempListener.onFailed(IOFailed);
181                         break;
182                     default:
183                         /** 这里不可能会进入,也当作一个留给你自己的接口吧 */
184                         break;
185                 }
186             }
187         };
188     }
189 
190     /** handler 发消息部分整合 */
191     private void sendMessage(int what,int code,Object object){
192         Message msg = new Message();
193         msg.what = what;
194         msg.arg1 = code;
195         msg.obj = object;
196         handler.sendMessage(msg);
197     }
198 
199     private void sendMessage(int what,Object object){
200         sendMessage(what, -1, object);
201     }
202 
203     /**
204      * requestCode 请求标识符,方便区分
205      * */
206 
207     /** Get 请求整合 */
208     public void doGet(final String url){
209         doGet(-1, url, null);
210     }
211 
212     public void doGet(final int requestCode,final String url){
213         doGet(requestCode, url, null);
214     }
215 
216     public void doGet(
217             final int requestCode,
218             final String url,
219             final LghHttpSingleListener lghHttpListeners)
220     {
221         Runnable runnable = new Runnable() {
222             @Override
223             public void run() {
224                 get(requestCode, url, lghHttpListeners);
225             }
226         };
227         if(threadPool != null){
228             threadPool.execute(runnable);
229         }else{
230             Log.d(TAG,"do get threadPool is null");
231         }
232     }
233 
234     private void get(int requestCode,String url,LghHttpSingleListener lghHttpListener){
235         try {
236             HttpURLConnection httpURLConnection = getHttpUrlConnection(url,"GET");
237             httpURLConnection.setUseCaches(false);
238             sendMessage(Success,requestCode, commonGetResult(httpURLConnection,lghHttpListener));
239         } catch (MalformedURLException e) {
240             dealWithException(e,lghHttpListener);
241         } catch (IOException e) {
242             dealWithException(e,lghHttpListener);
243         }
244     }
245 
246     /** Post 请求整合 */
247     public void doPost(String url){
248         doPost(-1, url);
249     }
250 
251     public void doPost(int requestCode,String url){
252         doPost(requestCode, url, null, null);
253     }
254 
255     public void doPost(int requestCode,String url,LghHttpSingleListener listener){
256         doPost(requestCode, url, null, null,listener);
257     }
258 
259     public void doPost(int requestCode,String url,String[] keys,String[] values){
260         doPost(requestCode, url, keys, values, null);
261     }
262 
263     public void doPost(
264             final int requestCode,
265             final String url,
266             final String[] keys,
267             final String[] values,
268             final LghHttpSingleListener listener
269     ){
270         Runnable runnable = new Runnable() {
271             @Override
272             public void run() {
273                 post(requestCode, url,keys,values, listener);
274             }
275         };
276         if(threadPool != null){
277             threadPool.execute(runnable);
278         }else{
279             Log.d(TAG,"do post threadPool is null");
280         }
281     }
282 
283     /** 采用第一种post协议,application/x-www-form-urlencoded */
284     private void post(
285             int requestCode,
286             String url,
287             String[] keys,
288             String[] values,
289             LghHttpSingleListener listener
290     ){
291         if(url==null){
292             return;
293         }
294         try{
295             HttpURLConnection httpURLConnection = getHttpUrlConnection(url,"POST");
296             httpURLConnection.setDoOutput(true); /** post 必不可少 */
297             httpURLConnection.setUseCaches(false);
298 
299             if(keys!=null && values!=null){
300                 OutputStream outputStream = httpURLConnection.getOutputStream();
301                 commonCombinePostText(keys,values,outputStream);
302                 outputStream.flush();
303                 outputStream.close();
304             }
305             sendMessage(Success,requestCode, commonGetResult(httpURLConnection,listener));
306         }catch (MalformedURLException e){
307             dealWithException(e,listener);
308         } catch (SocketTimeoutException e){
309             dealWithException(e,listener);
310         } catch (ProtocolException e) {
311             dealWithException(e,listener);
312         } catch (UnsupportedEncodingException e) {
313             dealWithException(e,listener);
314         } catch (IOException e) {
315             dealWithException(e,listener);
316         }
317     }
318 
319     /** 上传图片部分整合 */
320     public void doUpLoadPic(
321             String url,
322             String picName,
323             String streamName,
324             Bitmap bit
325     ){
326         doUpLoadPic(-1, url, null, null, picName, streamName, bit, null);
327     }
328 
329     public void doUpLoadPic(
330             int requestCode,
331             String url,
332             String picName,
333             String streamName,
334             Bitmap bit
335     ){
336         doUpLoadPic(requestCode, url, null, null, picName, streamName, bit, null);
337     }
338 
339     public void doUpLoadPic(
340             int requestCode,
341             String url,
342             String picName,
343             String streamName,
344             Bitmap bit,
345             LghHttpSingleListener listener
346     ){
347         doUpLoadPic(requestCode, url, null, null, picName, streamName, bit, listener);
348     }
349 
350     public void doUpLoadPic(
351             int requestCode,
352             String url,
353             String[] keys,
354             String[] values,
355             String picName,
356             String streamName,
357             Bitmap bit
358     ){
359         doUpLoadPic(requestCode, url, keys, values, picName, streamName, bit, null);
360     }
361 
362     public void doUpLoadPic(
363             final int requestCode,
364             final String url,
365             final String[] keys,
366             final String[] values,
367             final String picName,
368             final String streamName,
369             final Bitmap bit,
370             final LghHttpSingleListener listener
371     ){
372         Runnable runnable = new Runnable() {
373             @Override
374             public void run() {
375                 UpLoadPic(requestCode, url, keys, values, picName, streamName, bit, listener);
376             }
377         };
378         if(threadPool != null){
379             threadPool.execute(runnable);
380         }else{
381             Log.d(TAG,"do post threadPool is null");
382         }
383     }
384 
385     /**
386      * 此函数用来上传图片
387      * post 的 两种数据包格式:
388      * 1,application/x-www-form-urlencoded;用来上传文字
389      * 2,multipart/form-data; 二进制传输,除了文字之外,还可以用来传输 文件,例如图片!
390      * 3,multipart/form-data; 必须要带有分隔符 boundary
391      * 4,在http post请求的结尾,需要有一个分界线,但是是前后都有--的:--分隔符--
392      * 参数:
393      *      url
394      *      picName    图片的名称
395      *      streamName 流体值的名称
396      *      例如采用 php 接收,那么在服务器获取图片名称的写法是:$_FILES['streamName']['picName']
397      **/
398     private void UpLoadPic(
399             int requestCode,
400             String url,
401             String[] keys,
402             String[] values,
403             String picName,
404             String streamName,
405             Bitmap bit,
406             LghHttpSingleListener listener
407     ){
408         String twoHyphens = "--";   /** 一定要是 2行 */
409         String boundary = "******"; /** 数据包分割线可以自定义 */
410         try{
411             HttpURLConnection httpURLConnection = getHttpUrlConnection(url,"POST");
412             httpURLConnection.setUseCaches(false);
413             httpURLConnection.setDoOutput(true);
414             httpURLConnection.setChunkedStreamingMode(1024 * 256); /** 一次传输的块大小 */
415             /** 数据 --------包头-------- 格式组装 */
416             httpURLConnection.setRequestProperty("Connection","Keep-Alive");
417             httpURLConnection.setRequestProperty("Content-Type","multipart/form-data;boundary="+boundary);
418             /** 数据 --------包体-------- 格式组装*/
419             DataOutputStream body = new DataOutputStream(httpURLConnection.getOutputStream());
420             /** \r\n 是换行 */
421             body.writeBytes(twoHyphens+boundary+"\r\n"); /** 先写分隔符,标志和上面的头分开 */
422             body.writeBytes(
423                     "Content-Disposition:form-data;" +
424                             "name=\"" + streamName + "\";" +
425                             "filename=\"" + picName + "\"" + "\r\n"
426             );
427             /** 写文本数据体 */
428             body.writeBytes("\r\n");
429             if(keys!=null && values!=null){
430                 body.writeBytes(twoHyphens+boundary+"\r\n");
431                 body.writeBytes("Content-Disposition:form-data;");
432                 commonCombinePostText(keys,values,body);
433                 body.writeBytes("\r\n");
434             }
435             /** -------下面开始写图片二进制------- */
436             /** 下面是先压缩 */
437             int compress = 100;
438             ByteArrayOutputStream baos = new ByteArrayOutputStream();
439             bit.compress(Bitmap.CompressFormat.JPEG, compress, baos);
440             if(IsOpenCompress){
441                 while (baos.toByteArray().length / 1024 > CompressLimit) {
442                     baos.reset();
443                     compress -= 10;
444                     if(compress==0){
445                         bit.compress(Bitmap.CompressFormat.JPEG, compress, baos);
446                         break;
447                     }
448                     bit.compress(Bitmap.CompressFormat.JPEG, compress, baos);
449                 }
450             }
451             /** 开始写 */
452             InputStream picStream = new ByteArrayInputStream(baos.toByteArray());
453             byte[] buffer = new byte[10*1024];
454             int count;
455             while((count = picStream.read(buffer))!=-1){
456                 body.write(buffer,0,count);
457             }
458             picStream.close();
459             body.writeBytes("\r\n");
460             body.writeBytes(twoHyphens + boundary + twoHyphens +"\r\n");
461             body.flush();
462             /** 写完 */
463             sendMessage(Success,requestCode,commonGetResult(httpURLConnection,listener));
464             body.close();
465         }catch (MalformedURLException e){
466             dealWithException(e,listener);
467         } catch (SocketTimeoutException e){
468             dealWithException(e,listener);
469         } catch (ProtocolException e) {
470             dealWithException(e,listener);
471         } catch (UnsupportedEncodingException e) {
472             dealWithException(e,listener);
473         } catch (IOException e) {
474             dealWithException(e,listener);
475         }
476     }
477 
478     /** 公共部分,异常集合处理 */
479     private void dealWithException(
480             Exception e,
481             LghHttpSingleListener lghHttpListeners)
482     {
483         HttpDataBean bean = new HttpDataBean();
484         bean.setListeners(lghHttpListeners);
485         if(e instanceof MalformedURLException){
486             Log.d(TAG, "链接格式有问题 "+e.toString());
487             sendMessage(UrlFailed,bean);
488         }else if(e instanceof SocketTimeoutException){
489             Log.d(TAG, "连接超时 "+e.toString());
490             sendMessage(TimeOut,bean);
491         }else if(e instanceof ProtocolException){
492             Log.d(TAG, "协议异常,注意不要多次连接 " + e.toString());
493             sendMessage(ProtocolFailed, bean);
494         }else if(e instanceof UnsupportedEncodingException){
495             Log.d(TAG, "编码类型异常 " + e.toString());
496             sendMessage(EncodingFailed, bean);
497         }else if(e instanceof IOException){
498             Log.d(TAG, "io 异常 " + e.toString());
499             sendMessage(IOFailed,bean);
500         }
501     }
502 
503     /** 获取一个HttpUrlConnection,合并一些公共部分 */
504     private static HttpURLConnection getHttpUrlConnection
505             (String url,String requestWay) throws IOException {
506         Log.d(TAG,"url is "+url);
507         URL mRrl = new URL(url);
508         HttpURLConnection httpURLConnection = (HttpURLConnection) mRrl.openConnection();
509         httpURLConnection.setRequestMethod(requestWay);
510         httpURLConnection.setRequestProperty("Charset", "UTF-8");
511         httpURLConnection.setConnectTimeout(5 * 1000);
512         return httpURLConnection;
513     }
514 
515     /** 获取结果公共部分 */
516     private HttpDataBean commonGetResult(
517             HttpURLConnection httpURLConnection,
518             LghHttpSingleListener listener
519     ) throws IOException {
520         if(httpURLConnection==null){
521             return null;
522         }
523         BufferedReader br = new BufferedReader
524                 (
525                         new InputStreamReader(httpURLConnection.getInputStream(),"UTF-8"),
526                         8*1024
527                 );
528         StringBuffer resultBuffer = new StringBuffer("");
529         String line;
530         while ((line = br.readLine())!=null){
531             resultBuffer.append(line);
532         }
533         HttpDataBean bean = new HttpDataBean();
534         bean.setResponse(resultBuffer.toString());
535         bean.setListeners(listener);
536         br.close();
537         return bean;
538     }
539 
540     /** 组合 post 文本数据公共部分 */
541     private OutputStream commonCombinePostText(
542             String[] keys,
543             String[] values,
544             OutputStream outputStream) throws IOException
545     {
546         StringBuffer requestStr = new StringBuffer();
547         int keysLength = keys.length;
548         for(int i=0;i<keysLength;i++){
549             requestStr.append(keys[i]+"="+values[i]+"&");
550         }
551         outputStream.write(requestStr.toString().getBytes());
552         return outputStream;
553     }
554 
555     /** 接口分离 */
556     private interface LghHttpBaseListenr{
557         void onFailed(int type);
558 //        void onUrlFailed();
559 //        void onTimeOut();
560 //        void onProtocolFailed();
561 //        void onEncodingFailed();
562 //        void onIoFailed();
563     }
564 
565     /** 全局有 requestCode 区分 */
566     public interface LghHttpGlobleListener extends LghHttpBaseListenr{
567         void onSuccess(int requestCode,String response);
568     }
569 
570     /** 单一的没 requestCode 区分 */
571     public interface LghHttpSingleListener extends LghHttpBaseListenr{
572         void onSuccess(String response);
573     }
574 
575 }Copy the code

 

 

Usage example

1 package lgh.httpdemo; 2 3 import android.graphics.BitmapFactory; 4 import android.os.Bundle; 5 import android.support.v7.app.AppCompatActivity; 6 import android.util.Log; 7 import android.widget.Toast; 8 9 public class MainActivity extends AppCompatActivity { 10 11 private LghHttp lghHttp = LghHttp.getInstance(); 12 13 @Override 14 protected void onCreate(Bundle savedInstanceState) { 15 super.onCreate(savedInstanceState); 16 setContentView(R.layout.activity_main); 17 18 19 / / * * Example 1 * / * * use of global interface and a post operation * / 20 lghHttp setGloblelghHttpListeners (new LghHttp.LghHttpGlobleListener() { 21 @Override 22 public void onFailed(int type) { 23 switch (type) { 24 case LghHttp.UrlFailed: 25 26 break; 27 case LghHttp.Success: 28 29 break; 30 case LghHttp.TimeOut: 31 32 break; 33 / * *... */ 34 } 35 } 36 37 @Override 38 public void onSuccess(int requestCode, String response) { 39 Log.d("zzzzz", "LghHttpGlobleListener do post response " 40 + response + " requestCode is " + requestCode); 40 Switch (requestCode) {42 case 123:43 /** Corresponding operation */ 44 break; 45} 46} 47 48}); 49 for(int i=0; i<30; i++){ 50 final int j = i; 51 lghHttp. DoPost 52 (53 j, 54 "http://121.42.190.18/ydnurse/Controller/noteController.php? func=GetNote", 55 null 56 ); 58 / / 57} with the key value of 59 lghHttp. DoPost (60, 61, 145, 62 "http://121.42.190.18/ydnurse/Controller/noteController.php? Func =GetNote", 63 new String[]{"userName","userAge","userSex"}, 64 new String[]{" Box","21","Box"}, 65 null 66); 67 68 /** ----- Test the following example, ----- */ 69 /** Example 2 */ 70 lghhttp. doGet 71 (72 123, 73 "http://121.42.190.18/ydnurse/Controller/noteController.php? func=GetNote", 74 new LghHttp.LghHttpSingleListener() { 75 @Override 76 public void onSuccess(String response) { 77 78 } 79 80 @Override 81 public void onFailed(int type) { 82 83 } 84 } 85 ); 86 /** UpPic Example 3 */ 87 88 lghHttp.doUpLoadPic( 89 "http://www.xiangjiaoyun.com:8888/BCapp/BananaCloudServer/userPicUploadFile.php?" + 90 "account=13726204215&postid=0&type=2", 91 "123.jpg", 92 "uploadedfile", 93 BitmapFactory.decodeResource(getResources(), R.mipmap.ic_launcher) 94 ); 95 96 lghHttp.doUpLoadPic( 97 1456, 98 "http://www.xiangjiaoyun.com:8888/BCapp/BananaCloudServer/userPicUploadFile.php?" + 99 "account=13726204215&postid=0&type=2", 100 "123.jpg", 101 "uploadedfile", 102 BitmapFactory.decodeResource(getResources(), R.mipmap.ic_launcher), 103 new LghHttp.LghHttpSingleListener() { 104 @Override 105 public void onSuccess(String response) { 106 Toast.maketext (mainactivity.this," upload image successfully ", toast.length_short).show(); 107 } 108 109 @Override 110 public void onFailed(int type) { 111 112 } 113 } 114 ); 116 115}}Copy the code

 

If you think this article is good or informative, you can passScan the Alipay QR code belowTip me a cup of coffee [material support], you can also click on the lower right corner“Recommended”Button [spiritual support], because these two kinds of support are the biggest motivation for me to continue to write and share