代碼已經上傳到github,歡迎Star。
https://github.com/MZCretin/HttpUrlConnectionUtilDemo
轉載請註明出處:http://blog.csdn.net/u010998327/article/details/65443615
簡書地址:http://www.jianshu.com/p/3da7f0dc11a0
一個自己封裝的用HttpUrlConnection請求的網絡工具類,但只適合新手研究或者做些小demo用下, 畢竟現在對於Android開發的網絡框架有很多,而且很好很強大。
- 目前支持的功能:
1、GET,POST請求
2、支持返回String,Byte[]數組,以及自定義的Model類
3、請求的回調已處理過,現在的回調在UI線程,所以可以直接更新UI
同樣的,如果寫demo啥的,可以按照以下方式依賴進項目:
allprojects {
repositories {
...
maven { url 'https://jitpack.io' }
}
}
dependencies {
compile 'com.github.MZCretin:HttpUrlConnectionUtilDemo:v1.0'
}
後面如果有需要,我會加上下載文件的方法。
如果有啥問題,歡迎交流:
792075058
正文
最近吃膩了外賣,想着自己做飯吃,所以就自己做了一個菜譜的小軟件,從api服務上找了一個菜譜的接口就開始做了,在做的過程中,需要請求一個接口,來獲取菜譜信息,於是就想到Android現在很火的各種網絡框架。。。在選擇的時候就犯難了,我就寫個軟件自己用,就簡單的請求一個接口,有必要用這麼重的框架麼。然後就開始了主題所說的自定義一個簡單的網絡加載工具類。
我這邊只是做了一個簡單的封裝。
首先:定義一個 static ExecutorService threadPool = Executors.newCachedThreadPool(),來創建一個可根據需要創建新線程的線程池,但是在以前構造的線程可用時將重用它們。因爲不能在主線程請求網絡,所以用這個線程池來裝載我們用於進行網絡請求的線程,定義一個static Gson gson = new Gson();用來將請求的json數據轉換成對應的Model對象。
然後:定義第一個方法,也就是返回字符串的方法。在這個方法裏,上面有關HttpURLConnection的操作都是一樣的,不一樣的是最後對流的處理,這個方法要求返回的是字符串,所以我們在獲取到流的時候將其轉化成我們需要的字符串,再通過回調給調用者,其他goGet方法也一樣,如果需要byte數組,我們就返回byte數組,如果需要對象,我們就先轉成String字符串,然後通過gson將json字符串轉換成對應的對象返回即可。(具體請看源碼,下面會貼出源碼)
doGet方法
/**
* GET方法 返回數據會解析成字符串String
* @param context 上下文
* @param urlString 請求的url
* @param listener 回調監聽
*/
public static void doGet(final Context context, final String urlString,
final HttpCallbackStringListener listener) {
// 因爲網絡請求是耗時操作,所以需要另外開啓一個線程來執行該任務。
threadPool.execute(new Runnable() {
@Override
public void run() {
URL url;
HttpURLConnection httpURLConnection = null;
try {
// 根據URL地址創建URL對象
url = new URL(urlString);
// 獲取HttpURLConnection對象
httpURLConnection = ( HttpURLConnection ) url.openConnection();
// 設置請求方式,默認爲GET
httpURLConnection.setRequestMethod("GET");
// 設置連接超時
httpURLConnection.setConnectTimeout(5000);
// 設置讀取超時
httpURLConnection.setReadTimeout(8000);
// 響應碼爲200表示成功,否則失敗。
if ( httpURLConnection.getResponseCode() == 200 ) {
// 獲取網絡的輸入流
InputStream is = httpURLConnection.getInputStream();
BufferedReader bf = new BufferedReader(new InputStreamReader(is, "UTF-8"));
//最好在將字節流轉換爲字符流的時候 進行轉碼
StringBuffer buffer = new StringBuffer();
String line = "";
while ( (line = bf.readLine()) != null ) {
buffer.append(line);
}
bf.close();
is.close();
new ResponseCall(context, listener).doSuccess(buffer.toString());
} else {
new ResponseCall(context, listener).doFail(
new NetworkErrorException("response err code:" +
httpURLConnection.getResponseCode()));
}
} catch ( MalformedURLException e ) {
if ( listener != null ) {
// 回調onError()方法
new ResponseCall(context, listener).doFail(e);
}
} catch ( IOException e ) {
if ( listener != null ) {
// 回調onError()方法
new ResponseCall(context, listener).doFail(e);
}
} finally {
if ( httpURLConnection != null ) {
// 釋放資源
httpURLConnection.disconnect();
}
}
}
});
}
上面講了doGet方法的實現,其實doPost方法的實現除了需要帶上參數列表之外其他都是是一樣的。對於參數的處理,在我的開發經歷中,參數都是放在Map容器中傳遞的,所以在這裏也就使用的這種方式,對於傳進來的參數,我們需要進行處理下,其實也就是字符串的拼接,拼接成HttpURLConnection能夠識別的形式。下面的代碼進行了參數的組織:
final StringBuffer out = new StringBuffer();
// 組織請求參數
for (String key : params.keySet()) {
if(out.length()!=0){
out.append("&");
}
out.append(key).append("=").append(params.get(key));
}
拼接好參數列表之後,我們通過httpURLConnection.getOutputStream()獲取到PrintWriter,然後寫入我們的參數信息即可。其他的操作跟get請求是一樣的。
PrintWriter printWriter = new PrintWriter(httpURLConnection.getOutputStream());
// 發送請求參數
printWriter.write(out.toString());
// flush輸出流的緩衝
printWriter.flush();
printWriter.close();
doPost方法
/**
* POST方法 返回數據會解析成字符串 String
* @param context 上下文
* @param urlString 請求的路徑
* @param listener 回調監聽
* @param params 參數列表
*/
public static void doPost(final Context context,
final String urlString, final HttpCallbackStringListener listener,
final Map<String, Object> params) {
final StringBuffer out = new StringBuffer();
// 組織請求參數
for (String key : params.keySet()) {
if(out.length()!=0){
out.append("&");
}
out.append(key).append("=").append(params.get(key));
}
// 因爲網絡請求是耗時操作,所以需要另外開啓一個線程來執行該任務。
threadPool.execute(new Runnable() {
@Override
public void run() {
URL url;
HttpURLConnection httpURLConnection = null;
try {
url = new URL(urlString);
httpURLConnection = ( HttpURLConnection ) url.openConnection();
httpURLConnection.setRequestProperty("accept", "*/*");
httpURLConnection.setRequestProperty("connection", "Keep-Alive");
httpURLConnection.setRequestProperty("Content-Length", String
.valueOf(out.length()));
httpURLConnection.setRequestMethod("POST");
httpURLConnection.setConnectTimeout(5000);
httpURLConnection.setReadTimeout(8000);
// 設置運行輸入
httpURLConnection.setDoInput(true);
// 設置運行輸出
httpURLConnection.setDoOutput(true);
PrintWriter printWriter = new PrintWriter(httpURLConnection.getOutputStream());
// 發送請求參數
printWriter.write(out.toString());
// flush輸出流的緩衝
printWriter.flush();
printWriter.close();
if ( httpURLConnection.getResponseCode() == 200 ) {
// 獲取網絡的輸入流
InputStream is = httpURLConnection.getInputStream();
BufferedReader bf = new BufferedReader(new InputStreamReader(is, "UTF-8"));
//最好在將字節流轉換爲字符流的時候 進行轉碼
StringBuffer buffer = new StringBuffer();
String line = "";
while ( (line = bf.readLine()) != null ) {
buffer.append(line);
}
bf.close();
is.close();
new ResponseCall(context, listener).doSuccess(buffer.toString());
} else {
new ResponseCall(context, listener).doFail(
new NetworkErrorException("response err code:" +
httpURLConnection.getResponseCode()));
}
} catch ( MalformedURLException e ) {
if ( listener != null ) {
// 回調onError()方法
new ResponseCall(context, listener).doFail(e);
}
} catch ( IOException e ) {
if ( listener != null ) {
// 回調onError()方法
new ResponseCall(context, listener).doFail(e);
}
} finally {
if ( httpURLConnection != null ) {
// 最後記得關閉連接
httpURLConnection.disconnect();
}
}
}
});
}
在上面的代碼中,在請求的最後,我們會看到一個 new ResponseCall(context, listener).doSuccess(buffer.toString());這個是用來幹嘛的呢?其實這個是用來進行子線程和主線程的數據交換的,定義一個Handler,不過Handler是通過looper來創建的,looper是通過傳進來的上下文Context來獲取主線程的looper,然後次Handler就是位於主線程的。當請求結束後,如果請求成功,則調用doSuccess(T response)方法,給Handler發送消息,消息的what值爲0,消息的內容是請求的結果;請求失敗或錯誤的時候,調用doFail(Exception e)方法,給Handler發送消息,消息的what值爲1,消息的內容是請求失敗的異常信息。當Handler收到消息之後,直接調用listener的回調方法,就可以一方面把數據回調回去,另一方面,回調也是處於主線程也就是UI線程了,這樣調用者就可以直接在回調方法中更新UI了。
ResponseCall.java
/**
* Created by cretin on 2017/3/20.
*/
public class ResponseCall<T> {
//用於在子線程和主線程的數據交換
Handler mHandler;
public ResponseCall(Context context, final HttpCallbackModelListener listener) {
Looper looper = context.getMainLooper();
mHandler = new Handler(looper) {
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
if ( msg.what == 0 ) {
//成功
listener.onFinish(msg.obj);
} else if ( msg.what == 1 ) {
//失敗
listener.onError(( Exception ) msg.obj);
}
}
};
}
public ResponseCall(Context context, final HttpCallbackBytesListener listener) {
Looper looper = context.getMainLooper();
mHandler = new Handler(looper) {
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
if ( msg.what == 0 ) {
//成功
listener.onFinish(( byte[] ) msg.obj);
} else if ( msg.what == 1 ) {
//失敗
listener.onError(( Exception ) msg.obj);
}
}
};
}
public ResponseCall(Context context, final HttpCallbackStringListener listener) {
Looper looper = context.getMainLooper();
mHandler = new Handler(looper) {
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
if ( msg.what == 0 ) {
//成功
listener.onFinish(msg.obj.toString());
} else if ( msg.what == 1 ) {
//失敗
listener.onError(( Exception ) msg.obj);
}
}
};
}
public void doSuccess(T response) {
Message message = Message.obtain();
message.obj = response;
message.what = 0;
mHandler.sendMessage(message);
}
public void doFail(Exception e) {
Message message = Message.obtain();
message.obj = e;
message.what = 1;
mHandler.sendMessage(message);
}
}
下面是實際中的調用實例:
MainActivity.java
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.widget.TextView;
import com.cretin.www.httpurlconnectionutil.HttpUtils;
import com.cretin.www.httpurlconnectionutil.callback.HttpCallbackBytesListener;
import com.cretin.www.httpurlconnectionutil.callback.HttpCallbackModelListener;
import com.cretin.www.httpurlconnectionutil.callback.HttpCallbackStringListener;
import com.cretin.www.httpurlconnectionutildemo.model.ResponseModel;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.HashMap;
import java.util.Map;
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final TextView tvContent = ( TextView ) findViewById(R.id.tv_content);
//測試GET請求
//返回字符串
try {
HttpUtils.doGet(this, "http://caipu.yjghost.com/index.php/query/read?menu=" + URLEncoder.encode("土豆", "UTF-8") + "&rn=15&start=1", new HttpCallbackStringListener() {
@Override
public void onFinish(String response) {
tvContent.setText(response);
}
@Override
public void onError(Exception e) {
tvContent.setText(e.toString());
}
});
} catch ( UnsupportedEncodingException e ) {
e.printStackTrace();
}
//返回byte數組
try {
HttpUtils.doGet(this, "http://caipu.yjghost.com/index.php/query/read?menu=" + URLEncoder.encode("土豆", "UTF-8") + "&rn=15&start=1", new HttpCallbackBytesListener() {
@Override
public void onFinish(byte[] response) {
Log.e("HHHHHHH", "GET 方法:" + new String(response));
}
@Override
public void onError(Exception e) {
Log.e("HHHHHHH", "doGet onError:" + e.toString());
}
});
} catch ( UnsupportedEncodingException e ) {
e.printStackTrace();
}
//返回對象
try {
HttpUtils.doGet(this, "http://caipu.yjghost.com/index.php/query/read?menu=" +
URLEncoder.encode("土豆", "UTF-8") + "&rn=15&start=1",
new HttpCallbackModelListener<ResponseModel>() {
@Override
public void onFinish(ResponseModel response) {
Log.e("HHHHHHH", "GET 方法:" + response.getResult().getTotalNum());
}
@Override
public void onError(Exception e) {
Log.e("HHHHHHH", "doGet onError:" + e.toString());
}
}, ResponseModel.class);
} catch ( UnsupportedEncodingException e ) {
e.printStackTrace();
}
//測試POST請求
//參數列表
Map<String, Object> map = new HashMap<>();
map.put("productFirstType", "1");
map.put("loanRange", "1");
map.put("type", "hot");
map.put("page", "1");
map.put("timeRange", "1");
//返回String
HttpUtils.doPost(this, "http://101.201.31.212:8016/product/listProduct", new HttpCallbackStringListener() {
@Override
public void onFinish(String response) {
Log.e("HHHHHHH", "POST 方法:" + response);
}
@Override
public void onError(Exception e) {
Log.e("HHHHHHH", "doPost onError:" + e.toString());
}
}, map);
//返回byte數組
HttpUtils.doPost(this, "http://101.201.31.212:8016/product/listProduct", new HttpCallbackBytesListener() {
@Override
public void onFinish(byte[] response) {
Log.e("HHHHHHH", "POST 方法:" + new String(response));
}
@Override
public void onError(Exception e) {
Log.e("HHHHHHH", "doPost onError:" + e.toString());
}
}, map);
//返回對象
HttpUtils.doPost(this, "http://101.201.31.212:8016/product/listProduct", new HttpCallbackModelListener<ResponseModel>() {
@Override
public void onFinish(ResponseModel response) {
Log.e("HHHHHHH", "POST 方法:" + response.getResult().getTotalNum());
}
@Override
public void onError(Exception e) {
Log.e("HHHHHHH", "doPost onError:" + e.toString());
}
}, map, ResponseModel.class);
}
}
下面貼出整個工具類的代碼:
import android.accounts.NetworkErrorException;
import android.content.Context;
import com.cretin.www.httpurlconnectionutil.callback.HttpCallbackBytesListener;
import com.cretin.www.httpurlconnectionutil.callback.HttpCallbackModelListener;
import com.cretin.www.httpurlconnectionutil.callback.HttpCallbackStringListener;
import com.cretin.www.httpurlconnectionutil.response.ResponseCall;
import com.google.gson.Gson;
import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.Iterator;
import java.util.Map;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
/**
* Created by cretin on 2017/3/22.
* HttpURLConnection 網絡請求工具類
*
* 數據的請求都是基於HttpURLConnection的 請求成功與失敗的回調都是在主線程
* 可以直接更新UI
*/
public class HttpUtils {
static ExecutorService threadPool = Executors.newCachedThreadPool();
static Gson gson = new Gson();
/**
* GET方法 返回數據會解析成字符串String
* @param context 上下文
* @param urlString 請求的url
* @param listener 回調監聽
*/
public static void doGet(final Context context, final String urlString,
final HttpCallbackStringListener listener) {
// 因爲網絡請求是耗時操作,所以需要另外開啓一個線程來執行該任務。
threadPool.execute(new Runnable() {
@Override
public void run() {
URL url;
HttpURLConnection httpURLConnection = null;
try {
// 根據URL地址創建URL對象
url = new URL(urlString);
// 獲取HttpURLConnection對象
httpURLConnection = ( HttpURLConnection ) url.openConnection();
// 設置請求方式,默認爲GET
httpURLConnection.setRequestMethod("GET");
// 設置連接超時
httpURLConnection.setConnectTimeout(5000);
// 設置讀取超時
httpURLConnection.setReadTimeout(8000);
// 響應碼爲200表示成功,否則失敗。
if ( httpURLConnection.getResponseCode() == 200 ) {
// 獲取網絡的輸入流
InputStream is = httpURLConnection.getInputStream();
BufferedReader bf = new BufferedReader(new InputStreamReader(is, "UTF-8"));
//最好在將字節流轉換爲字符流的時候 進行轉碼
StringBuffer buffer = new StringBuffer();
String line = "";
while ( (line = bf.readLine()) != null ) {
buffer.append(line);
}
bf.close();
is.close();
new ResponseCall(context, listener).doSuccess(buffer.toString());
} else {
new ResponseCall(context, listener).doFail(
new NetworkErrorException("response err code:" +
httpURLConnection.getResponseCode()));
}
} catch ( MalformedURLException e ) {
if ( listener != null ) {
// 回調onError()方法
new ResponseCall(context, listener).doFail(e);
}
} catch ( IOException e ) {
if ( listener != null ) {
// 回調onError()方法
new ResponseCall(context, listener).doFail(e);
}
} finally {
if ( httpURLConnection != null ) {
// 釋放資源
httpURLConnection.disconnect();
}
}
}
});
}
/**
* GET方法 返回數據會解析成byte[]數組
* @param context 上下文
* @param urlString 請求的url
* @param listener 回調監聽
*/
public static void doGet(final Context context, final String urlString,
final HttpCallbackBytesListener listener) {
// 因爲網絡請求是耗時操作,所以需要另外開啓一個線程來執行該任務。
threadPool.execute(new Runnable() {
@Override
public void run() {
URL url = null;
HttpURLConnection httpURLConnection = null;
try {
// 根據URL地址創建URL對象
url = new URL(urlString);
// 獲取HttpURLConnection對象
httpURLConnection = ( HttpURLConnection ) url.openConnection();
// 設置請求方式,默認爲GET
httpURLConnection.setRequestMethod("GET");
// 設置連接超時
httpURLConnection.setConnectTimeout(5000);
// 設置讀取超時
httpURLConnection.setReadTimeout(8000);
// 響應碼爲200表示成功,否則失敗。
if ( httpURLConnection.getResponseCode() != 200 ) {
new ResponseCall(context, listener).doFail(
new NetworkErrorException("response err code:" +
httpURLConnection.getResponseCode()));
} else {
// 獲取網絡的輸入流
InputStream is = httpURLConnection.getInputStream();
// 讀取輸入流中的數據
BufferedInputStream bis = new BufferedInputStream(is);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
byte[] bytes = new byte[1024];
int len = -1;
while ( (len = bis.read(bytes)) != -1 ) {
baos.write(bytes, 0, len);
}
bis.close();
is.close();
// 響應的數據
new ResponseCall(context, listener).doSuccess(baos.toByteArray());
}
} catch ( MalformedURLException e ) {
if ( listener != null ) {
// 回調onError()方法
new ResponseCall(context, listener).doFail(e);
}
} catch ( IOException e ) {
if ( listener != null ) {
// 回調onError()方法
new ResponseCall(context, listener).doFail(e);
}
} finally {
if ( httpURLConnection != null ) {
// 釋放資源
httpURLConnection.disconnect();
}
}
}
});
}
/**
* GET方法 返回數據會解析成cls對象
* @param context 上下文
* @param urlString 請求路徑
* @param listener 回調監聽
* @param cls 返回的對象
* @param <T> 監聽的泛型
*/
public static <T> void doGet(final Context context,
final String urlString,
final HttpCallbackModelListener listener, final Class<T> cls) {
// 因爲網絡請求是耗時操作,所以需要另外開啓一個線程來執行該任務。
threadPool.execute(new Runnable() {
@Override
public void run() {
URL url;
HttpURLConnection httpURLConnection = null;
try {
// 根據URL地址創建URL對象
url = new URL(urlString);
// 獲取HttpURLConnection對象
httpURLConnection = ( HttpURLConnection ) url.openConnection();
// 設置請求方式,默認爲GET
httpURLConnection.setRequestMethod("GET");
// 設置連接超時
httpURLConnection.setConnectTimeout(5000);
// 設置讀取超時
httpURLConnection.setReadTimeout(8000);
// 響應碼爲200表示成功,否則失敗。
if ( httpURLConnection.getResponseCode() == 200 ) {
// 獲取網絡的輸入流
InputStream is = httpURLConnection.getInputStream();
BufferedReader bf = new BufferedReader(new InputStreamReader(is, "UTF-8"));
//最好在將字節流轉換爲字符流的時候 進行轉碼
StringBuffer buffer = new StringBuffer();
String line = "";
while ( (line = bf.readLine()) != null ) {
buffer.append(line);
}
bf.close();
is.close();
new ResponseCall(context, listener).doSuccess(gson.fromJson(buffer.toString(), cls));
} else {
if ( listener != null ) {
// 回調onError()方法
new ResponseCall(context, listener).doFail(
new NetworkErrorException("response err code:" +
httpURLConnection.getResponseCode()));
}
}
} catch ( MalformedURLException e ) {
if ( listener != null ) {
// 回調onError()方法
new ResponseCall(context, listener).doFail(e);
}
} catch ( IOException e ) {
if ( listener != null ) {
// 回調onError()方法
new ResponseCall(context, listener).doFail(e);
}
} finally {
if ( httpURLConnection != null ) {
// 釋放資源
httpURLConnection.disconnect();
}
}
}
});
}
/**
* POST方法 返回數據會解析成字符串 String
* @param context 上下文
* @param urlString 請求的路徑
* @param listener 回調監聽
* @param params 參數列表
*/
public static void doPost(final Context context,
final String urlString, final HttpCallbackStringListener listener,
final Map<String, Object> params) {
final StringBuffer out = new StringBuffer();
// 組織請求參數
for (String key : params.keySet()) {
if(out.length()!=0){
out.append("&");
}
out.append(key).append("=").append(params.get(key));
}
// 因爲網絡請求是耗時操作,所以需要另外開啓一個線程來執行該任務。
threadPool.execute(new Runnable() {
@Override
public void run() {
URL url;
HttpURLConnection httpURLConnection = null;
try {
url = new URL(urlString);
httpURLConnection = ( HttpURLConnection ) url.openConnection();
httpURLConnection.setRequestProperty("accept", "*/*");
httpURLConnection.setRequestProperty("connection", "Keep-Alive");
httpURLConnection.setRequestProperty("Content-Length", String
.valueOf(out.length()));
httpURLConnection.setRequestMethod("POST");
httpURLConnection.setConnectTimeout(5000);
httpURLConnection.setReadTimeout(8000);
// 設置運行輸入
httpURLConnection.setDoInput(true);
// 設置運行輸出
httpURLConnection.setDoOutput(true);
PrintWriter printWriter = new PrintWriter(httpURLConnection.getOutputStream());
// 發送請求參數
printWriter.write(out.toString());
// flush輸出流的緩衝
printWriter.flush();
printWriter.close();
if ( httpURLConnection.getResponseCode() == 200 ) {
// 獲取網絡的輸入流
InputStream is = httpURLConnection.getInputStream();
BufferedReader bf = new BufferedReader(new InputStreamReader(is, "UTF-8"));
//最好在將字節流轉換爲字符流的時候 進行轉碼
StringBuffer buffer = new StringBuffer();
String line = "";
while ( (line = bf.readLine()) != null ) {
buffer.append(line);
}
bf.close();
is.close();
new ResponseCall(context, listener).doSuccess(buffer.toString());
} else {
new ResponseCall(context, listener).doFail(
new NetworkErrorException("response err code:" +
httpURLConnection.getResponseCode()));
}
} catch ( MalformedURLException e ) {
if ( listener != null ) {
// 回調onError()方法
new ResponseCall(context, listener).doFail(e);
}
} catch ( IOException e ) {
if ( listener != null ) {
// 回調onError()方法
new ResponseCall(context, listener).doFail(e);
}
} finally {
if ( httpURLConnection != null ) {
// 最後記得關閉連接
httpURLConnection.disconnect();
}
}
}
});
}
/**
* POST方法 返回數據會解析成Byte[]數組
* @param context 上下文
* @param urlString 請求的路徑
* @param listener 回調監聽
* @param params 參數列表
*/
public static void doPost(final Context context,
final String urlString, final HttpCallbackBytesListener listener,
final Map<String, Object> params) {
final StringBuffer out = new StringBuffer();
// 組織請求參數
for (String key : params.keySet()) {
if(out.length()!=0){
out.append("&");
}
out.append(key).append("=").append(params.get(key));
}
// 因爲網絡請求是耗時操作,所以需要另外開啓一個線程來執行該任務。
threadPool.execute(new Runnable() {
@Override
public void run() {
URL url;
HttpURLConnection httpURLConnection = null;
try {
url = new URL(urlString);
httpURLConnection = ( HttpURLConnection ) url.openConnection();
httpURLConnection.setRequestProperty("accept", "*/*");
httpURLConnection.setRequestProperty("connection", "Keep-Alive");
httpURLConnection.setRequestProperty("Content-Length", String
.valueOf(out.length()));
httpURLConnection.setRequestMethod("POST");
httpURLConnection.setConnectTimeout(5000);
httpURLConnection.setReadTimeout(8000);
// 設置運行輸入
httpURLConnection.setDoInput(true);
// 設置運行輸出
httpURLConnection.setDoOutput(true);
PrintWriter printWriter = new PrintWriter(httpURLConnection.getOutputStream());
// 發送請求參數
printWriter.write(out.toString());
// flush輸出流的緩衝
printWriter.flush();
printWriter.close();
if ( httpURLConnection.getResponseCode() == 200 ) {
// 獲取網絡的輸入流
InputStream is = httpURLConnection.getInputStream();
// 讀取輸入流中的數據
BufferedInputStream bis = new BufferedInputStream(is);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
byte[] bytes = new byte[1024];
int len = -1;
while ( (len = bis.read(bytes)) != -1 ) {
baos.write(bytes, 0, len);
}
bis.close();
is.close();
// 響應的數據
new ResponseCall(context, listener).doSuccess(baos.toByteArray());
} else {
new ResponseCall(context, listener).doFail(
new NetworkErrorException("response err code:" +
httpURLConnection.getResponseCode()));
}
} catch ( MalformedURLException e ) {
if ( listener != null ) {
// 回調onError()方法
new ResponseCall(context, listener).doFail(e);
}
} catch ( IOException e ) {
if ( listener != null ) {
// 回調onError()方法
new ResponseCall(context, listener).doFail(e);
}
} finally {
if ( httpURLConnection != null ) {
// 最後記得關閉連接
httpURLConnection.disconnect();
}
}
}
});
}
/**
* /**
* POST方法 返回數據會解析成cls對象
* @param context 上下文
* @param urlString 請求的路徑
* @param listener 回調監聽
* @param params 參數列表
* @param cls 對象
* @param <T> 監聽泛型
*/
public static <T> void doPost(final Context context,
final String urlString, final HttpCallbackModelListener listener,
final Map<String, Object> params, final Class<T> cls) {
final StringBuffer paramsStr = new StringBuffer();
// 組織請求參數
Iterator it = params.entrySet().iterator();
while ( it.hasNext() ) {
Map.Entry element = ( Map.Entry ) it.next();
paramsStr.append(element.getKey());
paramsStr.append("=");
paramsStr.append(element.getValue());
paramsStr.append("&");
}
if ( paramsStr.length() > 0 ) {
paramsStr.deleteCharAt(paramsStr.length() - 1);
}
// 因爲網絡請求是耗時操作,所以需要另外開啓一個線程來執行該任務。
threadPool.execute(new Runnable() {
@Override
public void run() {
URL url;
HttpURLConnection httpURLConnection = null;
try {
url = new URL(urlString);
httpURLConnection = ( HttpURLConnection ) url.openConnection();
httpURLConnection.setRequestMethod("POST");
httpURLConnection.setConnectTimeout(5000);
httpURLConnection.setReadTimeout(8000);
// 設置運行輸入
httpURLConnection.setDoInput(true);
// 設置運行輸出
httpURLConnection.setDoOutput(true);
PrintWriter printWriter = new PrintWriter(httpURLConnection.getOutputStream());
// 發送請求參數
printWriter.write(paramsStr.toString());
// flush輸出流的緩衝
printWriter.flush();
printWriter.close();
if ( httpURLConnection.getResponseCode() == 200 ) {
// 獲取網絡的輸入流
InputStream is = httpURLConnection.getInputStream();
BufferedReader bf = new BufferedReader(new InputStreamReader(is, "UTF-8"));
//最好在將字節流轉換爲字符流的時候 進行轉碼
StringBuffer buffer = new StringBuffer();
String line = "";
while ( (line = bf.readLine()) != null ) {
buffer.append(line);
}
bf.close();
is.close();
new ResponseCall(context, listener).doSuccess(gson.fromJson(buffer.toString(), cls));
} else {
new ResponseCall(context, listener).doFail(
new NetworkErrorException("response err code:" +
httpURLConnection.getResponseCode()));
}
} catch ( MalformedURLException e ) {
if ( listener != null ) {
// 回調onError()方法
new ResponseCall(context, listener).doFail(e);
}
} catch ( IOException e ) {
if ( listener != null ) {
// 回調onError()方法
new ResponseCall(context, listener).doFail(e);
}
} finally {
if ( httpURLConnection != null ) {
// 最後記得關閉連接
httpURLConnection.disconnect();
}
}
}
});
}
}
HttpCallbackBytesListener.java
/**
* HttpURLConnection網絡請求返回監聽器
*/
public interface HttpCallbackBytesListener {
// 網絡請求成功
void onFinish(byte[] response);
// 網絡請求失敗
void onError(Exception e);
}
HttpCallbackModelListener.java
/**
* HttpURLConnection網絡請求返回監聽器
*/
public interface HttpCallbackModelListener<T> {
// 網絡請求成功
void onFinish(T response);
// 網絡請求失敗
void onError(Exception e);
}
HttpCallbackStringListener.java
/**
* HttpURLConnection網絡請求返回監聽器
*/
public interface HttpCallbackStringListener {
// 網絡請求成功
void onFinish(String response);
// 網絡請求失敗
void onError(Exception e);
}
代碼已經上傳到github,歡迎Star。
我叫Cretin,一個可愛的小男孩。