1. 程式人生 > >個人總結HTTP請求,下載圖片,圖片處理,IO流操作完整

個人總結HTTP請求,下載圖片,圖片處理,IO流操作完整

一共4個工具包
HttpTools   網路請求工具包,HttpClient和URLConnection都有介紹
BitmapTools   圖片處理工具包
ImageLoaderTools    圖片非同步雙快取下載工具包
StreamTools   圖片儲存到SDCarkd工具包
CookiesTools   網路通訊工具包
我寫了一個各個包之間的邏輯關係圖,每個包都可拿來就用。歡迎同學們共享,申請加精!
這個是HttpTools中的具體程式碼
[mw_shl_code=java,true]package com.cnki.client.utils;

import java.io.ByteArrayOutputStream;

import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.ProtocolException;
import java.net.URL;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.HashMap;

import java.util.Iterator;
import java.util.List;
import java.util.Map;

import javax.net.ssl.SSLHandshakeException;

import org.apache.http.Header;
import org.apache.http.HttpEntity;
import org.apache.http.HttpEntityEnclosingRequest;
import org.apache.http.HttpHost;
import org.apache.http.HttpRequest;

import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.NoHttpResponseException;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.CookieStore;
import org.apache.http.client.HttpRequestRetryHandler;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.methods.HttpUriRequest;
import org.apache.http.client.params.HttpClientParams;
import org.apache.http.conn.params.ConnRouteParams;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.params.BasicHttpParams;
import org.apache.http.params.HttpConnectionParams;
import org.apache.http.params.HttpParams;
import org.apache.http.protocol.ExecutionContext;
import org.apache.http.protocol.HTTP;
import org.apache.http.protocol.HttpContext;
import org.apache.http.util.EntityUtils;

import android.app.Activity;
import android.content.Context;
import android.os.Handler;
import android.webkit.DownloadListener;

public class HttpTools {
public static final int METHOD_GET = 1;
public static final int METHOD_POST = 2;

/** 執行downfile後,得到下載檔案的大小 */
private long contentLength;
/** 返回連線失敗資訊 **/
private String strResult = "伺服器無法連線,請檢查網路";

/** http 請求頭引數 **/
private HttpParams httpParams;
/** httpClient 物件 **/
private DefaultHttpClient httpClient;

/** 得到上下文 **/
private Context context;
private Activity activity = null;

/**更新介面UI**/
Handler mHandler;

/** HTTP幫助類的構造方法 */
public HttpTools(Context context) {
this.context = context;

getHttpClient();
}

public HttpTools() {}


/**
* 得到 apache http HttpClient物件 一般情況下,我們獲取httpclient物件就一句話,httpClient = new
* DefaultHttpClient();
* 但是這個DefaultHttpClient()方法中沒傳引數,少了許多引數限制,所以就下面這個方法,通過設定 HTTP引數來約束請求
* **/
public DefaultHttpClient getHttpClient() {
/** 建立 HttpParams 以用來設定 HTTP 引數 **/
httpParams = new BasicHttpParams();

/** 設定連線超時和 Socket 超時,以及 Socket 快取大小 **/

HttpConnectionParams.setConnectionTimeout(httpParams, 20 * 1000);

HttpConnectionParams.setSoTimeout(httpParams, 20 * 1000);

HttpConnectionParams.setSocketBufferSize(httpParams, 8192);
// 以新的方式重新訪問,這裡就是通過引數設定來訪問
/** 這裡就是HTTP訪問重定向的問題了,true的意思就是讓訪問重定向,get和post重定向設定相同 */
HttpClientParams.setRedirecting(httpParams, true);

/**
* 建立一個 HttpClient 例項 //增加自動選擇網路,自適應cmwap、CMNET、wifi或3G
*/
MyHttpCookies li = new MyHttpCookies(context);
// 可以理解為網路代理商
String proxyStr = li.getHttpProxyStr();
if (proxyStr != null && proxyStr.trim().length() > 0) {
HttpHost proxy = new HttpHost(proxyStr, 80);
httpClient.getParams().setParameter(ConnRouteParams.DEFAULT_PROXY,
proxy);
}
/** 注意 HttpClient httpClient = new HttpClient(); 是Commons HttpClient **/
httpClient = new DefaultHttpClient(httpParams);
// 設定請求異常時需要做出的處理 .為了開啟自定義異常恢復機制,應該提供一個HttpRequestRetryHandler介面的實現。
httpClient.setHttpRequestRetryHandler(requestRetryHandler);

return httpClient;

}

/**
* 異常自動恢復處理, 使用HttpRequestRetryHandler介面實現請求的異常恢復
*/
private static HttpRequestRetryHandler requestRetryHandler = new HttpRequestRetryHandler() {
// 自定義的恢復策略
public boolean retryRequest(IOException exception, int executionCount,
HttpContext context) {
// 設定恢復策略,在發生異常時候將自動重試N次
if (executionCount >= 3) {
// 如果超過最大重試次數,那麼就不要繼續了
return false;
}
if (exception instanceof NoHttpResponseException) {
// 如果伺服器丟掉了連線,那麼就重試
return true;
}
if (exception instanceof SSLHandshakeException) {
// 不要重試SSL握手異常
return false;
}
HttpRequest request = (HttpRequest) context
.getAttribute(ExecutionContext.HTTP_REQUEST);
boolean idempotent = (request instanceof HttpEntityEnclosingRequest);
if (!idempotent) {
// 如果請求被認為是冪等的,那麼就重試
return true;
}
return false;
}
};

/**

* 總的來說DoGet是不安全的,會把使用者的資訊暴露在URL中,但是在手機中酷似看不到,如果有人進行網路抓包的話,會抓到。
* 提供GET形式的訪問網路請求 doGet 引數示例:

* @param url
* 請求地址
@return 返回 String jsonResult;

*/
public String doGet(String url) {
/** 建立HttpGet物件 **/
HttpGet httpRequest = new HttpGet(url);
httpRequest.setHeaders(this.getHeader());
try {
/** 保持會話Session **/
/** 設定Cookie **/
MyHttpCookies li = new MyHttpCookies(context);
CookieStore cs = li.getuCookie();
/** 第一次請求App儲存的Cookie為空,所以什麼也不做,只有當APP的Cookie不為空的時。把請請求的Cooke放進去 **/
if (cs != null) {
httpClient.setCookieStore(li.getuCookie());
}

/** 保持會話Session end **/

/* 傳送請求並等待響應 */
HttpResponse httpResponse = httpClient.execute(httpRequest);
/* 若狀態碼為200 ok */
if (httpResponse.getStatusLine().getStatusCode() == 200) {
/* 讀返回資料 */
strResult = EntityUtils.toString(httpResponse.getEntity());

/** 執行成功之後得到 **/
/** 成功之後把返回成功的Cookis儲存APP中 **/
// 請求成功之後,每次都設定Cookis。保證每次請求都是最新的Cookis
li.setuCookie(httpClient.getCookieStore());

} else {
strResult = "Error Response: "
+ httpResponse.getStatusLine().toString();
}
} catch (ClientProtocolException e) {
strResult = nullToString(e.getMessage());
e.printStackTrace();
} catch (IOException e) {
strResult = nullToString(e.getMessage());
e.printStackTrace();
} catch (Exception e) {
strResult = nullToString(e.getMessage());
e.printStackTrace();
} finally {
httpRequest.abort();
this.shutDownClient();
}
return strResult;
}

/**
* 提供GET形式的訪問網路請求 doGet 引數示例: Map params=new HashMap();
* params.put("usename","helijun"); params.put("password","123456");
* httpClient.doGet(url,params);

* @param url
* 請求地址
* @param params
* 請求引數
* @return 返回 String jsonResult;

* **/
public String doGet(String url, Map params) {
/** 建立HTTPGet物件 **/
String paramStr = "";
if (params == null)
params = new H