一锚贱、Okhttp簡(jiǎn)介
Android為我們提供了兩種HTTP交互的方式: HttpURLConnection 和 Apache HTTP Client望拖,雖然兩者都支持
HTTPS悉尾,流的上傳和下載,配置超時(shí),IPv6和連接池,已足夠滿足我們各種HTTP請(qǐng)求的需求靠闭。但更高效的使用
HTTP可以讓您的應(yīng)用運(yùn)行更快、更節(jié)省流量坎炼。而OkHttp庫(kù)就是為此而生愧膀。
OkHttp是一個(gè)高效的HTTP庫(kù):
1.支持 SPDY ,共享同一個(gè)Socket來(lái)處理同一個(gè)服務(wù)器的所有請(qǐng)求
2.如果SPDY不可用谣光,則通過(guò)連接池來(lái)減少請(qǐng)求延時(shí)
3.無(wú)縫的支持GZIP來(lái)減少數(shù)據(jù)流量
4. 緩存響應(yīng)數(shù)據(jù)來(lái)減少重復(fù)的網(wǎng)絡(luò)請(qǐng)求
OkHttp會(huì)從很多常用的連接問(wèn)題中自動(dòng)恢復(fù)檩淋。如果您的服務(wù)器配置了多個(gè)IP地址,當(dāng)?shù)谝粋€(gè)IP連接失敗的時(shí)候萄金,
會(huì)自動(dòng)嘗試下一個(gè)IP蟀悦。OkHttp還處理了代理服務(wù)器問(wèn)題和SSL握手失敗問(wèn)題碳柱。
使用 OkHttp無(wú)需重寫(xiě)您程序中的網(wǎng)絡(luò)代碼。OkHttp實(shí)現(xiàn)了幾乎和java.net.HttpURLConnection一樣的API熬芜。如果您
用了 Apache HttpClient莲镣,則OkHttp也提供了一個(gè)對(duì)應(yīng)的okhttp-apache 模塊。
二涎拉、Okhttp用法
1瑞侮、Get 請(qǐng)求
OkHttpClient 客戶端對(duì)象
Request是OkHttp中訪問(wèn)的請(qǐng)求,
Builder是輔助類鼓拧。
Response即OkHttp中的響應(yīng)半火。
2、Http POST (JSON)
MediaType 數(shù)據(jù)類型
RequestBody 請(qǐng)求數(shù)據(jù)
3季俩、Http POST (FormData)
FormEncodingBuilder 表單構(gòu)造器
三钮糖、Okhttp的簡(jiǎn)單封裝
OkHttpHelper.java
public class OkHttpHelper {
public static final int TOKEN_MISSING=401;// token 丟失
public static final int TOKEN_ERROR=402; // token 錯(cuò)誤
public static final int TOKEN_EXPIRE=403; // token 過(guò)期
public static final String TAG="OkHttpHelper";
private static OkHttpHelper mInstance;
private OkHttpClient mHttpClient;
private Gson mGson;
private Handler mHandler;
static {
mInstance = new OkHttpHelper();
}
private OkHttpHelper(){
mHttpClient = new OkHttpClient();
mHttpClient.setConnectTimeout(10, TimeUnit.SECONDS);
mHttpClient.setReadTimeout(10,TimeUnit.SECONDS);
mHttpClient.setWriteTimeout(30,TimeUnit.SECONDS);
mGson = new Gson();
mHandler = new Handler(Looper.getMainLooper());
};
public static OkHttpHelper getInstance(){
return mInstance;
}
public void get(String url,Map<String,Object> param,BaseCallback callback){
Request request = buildGetRequest(url,param);
request(request,callback);
}
public void get(String url,BaseCallback callback){
get(url,null,callback);
}
public void post(String url,Map<String,Object> param, BaseCallback callback){
Request request = buildPostRequest(url,param);
request(request,callback);
}
public void request(final Request request,final BaseCallback callback){
callback.onBeforeRequest(request);
mHttpClient.newCall(request).enqueue(new Callback() {
@Override
public void onFailure(Request request, IOException e) {
callbackFailure(callback, request, e);
}
@Override
public void onResponse(Response response) throws IOException {
// callback.onResponse(response);
callbackResponse(callback,response);
if(response.isSuccessful()) {
String resultStr = response.body().string();
Log.d(TAG, "result=" + resultStr);
if (callback.mType == String.class){
callbackSuccess(callback,response,resultStr);
}
else {
try {
Object obj = mGson.fromJson(resultStr, callback.mType);
callbackSuccess(callback,response,obj);
}
catch (com.google.gson.JsonParseException e){ // Json解析的錯(cuò)誤
callback.onError(response,response.code(),e);
}
}
}
else if(response.code() == TOKEN_ERROR||response.code() == TOKEN_EXPIRE ||response.code() == TOKEN_MISSING ){
callbackTokenError(callback,response);
}
else {
callbackError(callback,response,null);
}
}
});
}
private void callbackTokenError(final BaseCallback callback , final Response response ){
mHandler.post(new Runnable() {
@Override
public void run() {
callback.onTokenError(response,response.code());
}
});
}
private void callbackSuccess(final BaseCallback callback , final Response response, final Object obj ){
mHandler.post(new Runnable() {
@Override
public void run() {
callback.onSuccess(response, obj);
}
});
}
private void callbackError(final BaseCallback callback , final Response response, final Exception e ){
mHandler.post(new Runnable() {
@Override
public void run() {
callback.onError(response,response.code(),e);
}
});
}
private void callbackFailure(final BaseCallback callback , final Request request, final IOException e ){
mHandler.post(new Runnable() {
@Override
public void run() {
callback.onFailure(request,e);
}
});
}
private void callbackResponse(final BaseCallback callback , final Response response ){
mHandler.post(new Runnable() {
@Override
public void run() {
callback.onResponse(response);
}
});
}
private Request buildPostRequest(String url,Map<String,Object> params){
return buildRequest(url,HttpMethodType.POST,params);
}
private Request buildGetRequest(String url,Map<String,Object> param){
return buildRequest(url,HttpMethodType.GET,param);
}
private Request buildRequest(String url,HttpMethodType methodType,Map<String,Object> params){
Request.Builder builder = new Request.Builder()
.url(url);
if (methodType == HttpMethodType.POST){
RequestBody body = builderFormData(params);
builder.post(body);
}
else if(methodType == HttpMethodType.GET){
url = buildUrlParams(url,params);
builder.url(url);
builder.get();
}
return builder.build();
}
private String buildUrlParams(String url ,Map<String,Object> params) {
if(params == null)
params = new HashMap<>(1);
String token = CniaoApplication.getInstance().getToken();
if(!TextUtils.isEmpty(token))
params.put("token",token);
StringBuffer sb = new StringBuffer();
for (Map.Entry<String, Object> entry : params.entrySet()) {
sb.append(entry.getKey() + "=" + (entry.getValue()==null?"":entry.getValue().toString()));
sb.append("&");
}
String s = sb.toString();
if (s.endsWith("&")) {
s = s.substring(0, s.length() - 1);
}
if(url.indexOf("?")>0){
url = url +"&"+s;
}else{
url = url +"?"+s;
}
return url;
}
private RequestBody builderFormData(Map<String,Object> params){
FormEncodingBuilder builder = new FormEncodingBuilder();
if(params !=null){
for (Map.Entry<String,Object> entry :params.entrySet() ){
builder.add(entry.getKey(),entry.getValue()==null?"":entry.getValue().toString());
}
String token = CniaoApplication.getInstance().getToken();
if(!TextUtils.isEmpty(token))
builder.add("token", token);
}
return builder.build();
}
enum HttpMethodType{
GET,
POST,
}
}
BaseCallback.java
public abstract class BaseCallback <T> {
public Type mType;
static Type getSuperclassTypeParameter(Class<?> subclass)
{
Type superclass = subclass.getGenericSuperclass();
if (superclass instanceof Class)
{
throw new RuntimeException("Missing type parameter.");
}
ParameterizedType parameterized = (ParameterizedType) superclass;
return $Gson$Types.canonicalize(parameterized.getActualTypeArguments()[0]);
}
public BaseCallback()
{
mType = getSuperclassTypeParameter(getClass());
}
public abstract void onBeforeRequest(Request request);
public abstract void onFailure(Request request, Exception e) ;
/**
*請(qǐng)求成功時(shí)調(diào)用此方法
* @param response
*/
public abstract void onResponse(Response response);
/**
*
* 狀態(tài)碼大于200,小于300 時(shí)調(diào)用此方法
* @param response
* @param t
* @throws IOException
*/
public abstract void onSuccess(Response response,T t) ;
/**
* 狀態(tài)碼400酌住,404店归,403,500等時(shí)調(diào)用此方法
* @param response
* @param code
* @param e
*/
public abstract void onError(Response response, int code,Exception e) ;
/**
* Token 驗(yàn)證失敗酪我。狀態(tài)碼401,402,403 等時(shí)調(diào)用此方法
* @param response
* @param code
*/
public abstract void onTokenError(Response response, int code);
}
SimpleCallback.java(處理Token的CallBack)
public abstract class SimpleCallback<T> extends BaseCallback<T> {
protected Context mContext;
public SimpleCallback(Context context){
mContext = context;
}
@Override
public void onBeforeRequest(Request request) {
}
@Override
public void onFailure(Request request, Exception e) {
}
@Override
public void onResponse(Response response) {
}
@Override
public void onTokenError(Response response, int code) {
ToastUtils.show(mContext, mContext.getString(R.string.token_error));
Intent intent = new Intent();
intent.setClass(mContext, LoginActivity.class);
mContext.startActivity(intent);
mApplication.getInstance().clearUser();
}
}
SpotsCallBack.java(包含加載框的CallBack)
public abstract class SpotsCallBack<T> extends SimpleCallback<T> {
private SpotsDialog mDialog;
public SpotsCallBack(Context context){
super(context);
initSpotsDialog();
}
private void initSpotsDialog(){
mDialog = new SpotsDialog(mContext,"拼命加載中...");
}
public void showDialog(){
mDialog.show();
}
public void dismissDialog(){
mDialog.dismiss();
}
public void setLoadMessage(int resId){
mDialog.setMessage(mContext.getString(resId));
}
@Override
public void onBeforeRequest(Request request) {
showDialog();
}
@Override
public void onResponse(Response response) {
dismissDialog();
}
}