仿京东商城系列3------封装Okhttp
本项目来自菜鸟窝,有兴趣者点击http://www.cniao5.com/course/
项目已经做完,源码地址。https://github.com/15829238397/CN5E-shop
仿京东商城系列0------项目简介
仿京东商城系列1------fragmentTabHost实现底部导航栏
仿京东商城系列2------自定义toolbar
仿京东商城系列3------封装Okhttp
仿京东商城系列4------轮播广告条
仿京东商城系列5------商品推荐栏
仿京东商城系列6------下拉刷新上拉加载的商品列表
仿京东商城系列7------商品分类页面
仿京东商城系列8------自定义的数量控制器
仿京东商城系列9------购物车数据存储器实现
仿京东商城系列10------添加购物车,管理购物车功能实现
仿京东商城系列11------商品排序功能以及布局切换实现(Tablayout)
仿京东商城系列12------商品详细信息展示(nativie与html交互)
仿京东商城系列13------商品分享(shareSDK)
仿京东商城系列14------用户登录以及app登录拦截
仿京东长城系列15------用户注册,SMSSDK集成
仿京东商城系列16------支付SDK集成
仿京东商城系列17------支付功能实现
仿京东商城系列18------xml文件读取(地址选择器)
仿京东商城系列19------九宫格订单展示
仿京东商城系列20------终章
前言
本文讲述Okhttp的封装过程,便于使用,不对源码部分进行深究。
推荐一篇文章
okhttp源码学习笔记(一)-- 综述
内容
基本使用
- 设置网络权限
在manifests文件中增加权限
<uses-permission android:name="android.permission.INTERNET"/>
- 添加依赖
compile 'com.squareup.okhttp:okhttp-urlconnection:2.7.5'
compile 'com.squareup.okhttp:okhttp:2.7.5'
- get请求
OkHttpClient client = new OkHttpClient() ;
client.setConnectTimeout(5 , TimeUnit.SECONDS);
client.setWriteTimeout(5 , TimeUnit.SECONDS);
client.setReadTimeout(5 , TimeUnit.SECONDS);
String url = "http://www.jianshu.com/p/6ffde18fb034" ;
Request request = new Request.Builder().url(url).get().build() ;
client.newCall(request).enqueue(new Callback() {
@Override
public void onFailure(Request request, IOException e) {
}
@Override
public void onResponse(Response response) throws IOException {
}
});
}
- post请求
OkHttpClient client = new OkHttpClient() ;
client.setConnectTimeout(5 , TimeUnit.SECONDS);
client.setWriteTimeout(5 , TimeUnit.SECONDS);
client.setReadTimeout(5 , TimeUnit.SECONDS);
String url = "http://www.jianshu.com/p/6ffde18fb034" ;
//盛放参数
RequestBody requestBody = new FormEncodingBuilder()
.add("name","xxx").build() ;
Request request = new Request.Builder().url(url).post(requestBody).build() ;
client.newCall(request).enqueue(new Callback() {
@Override
public void onFailure(Request request, IOException e) {
}
@Override
public void onResponse(Response response) throws IOException {
}
});
}
okhttp封装
由上面的简单使用,我们可以知道Okhttp的使用有几个重要的部分:
- client
- Requset
- Callback
我们将从这三方面对Okhttp进行封装。
先上代码:
package com.example.cne_shop.okhttp;
import android.app.Service;
import android.os.Handler;
import android.text.TextUtils;
import android.util.Log;
import com.example.cne_shop.myException.GET_RESPONSE_MESSAGE_FAILURE;
import com.example.cne_shop.myException.GSON_ANALYZE_MESSAGE_FAILURE;
import com.google.gson.Gson;
import com.squareup.okhttp.Callback;
import com.squareup.okhttp.FormEncodingBuilder;
import com.squareup.okhttp.OkHttpClient;
import com.squareup.okhttp.Request;
import com.squareup.okhttp.RequestBody;
import com.squareup.okhttp.Response;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;
/**
* Created by 博 on 2017/8/22.
*/
public class OkhttpHelper {
//所有的请求公用一个OkhttpClient
private static OkHttpClient client ;
private Handler handler ;
private Gson gson ;
private static final int TOKEN_ERROR = 401 ;
private static final int TOKEN_EXPRISE = 402 ;
private static final int TOKEN_MISSING = 403 ;
private OkhttpHelper(){
//初始化client信息
client = new OkHttpClient() ;
client.setConnectTimeout(5 , TimeUnit.SECONDS);
client.setWriteTimeout(5 , TimeUnit.SECONDS);
client.setReadTimeout(5 , TimeUnit.SECONDS);
gson = new Gson() ;
}
//提供一个静态方法供外部请求。
public static OkhttpHelper getOkhttpHelper(){
return new OkhttpHelper() ;
}
//提交get请求的方法。
public void doGet (String uri , BaseCallback callback){
doGet(uri , callback , null);
}
//带参数请求的方法
public void doGet (String uri , BaseCallback callback , Map<String , String> formData){
Request request = buildRequest(uri , METHOD_TYPE.GET , formData);
doRequest(request , callback);
}
public void doPost(String uri , BaseCallback callback , Map<String , String> formData){
Request request = buildRequest(uri , METHOD_TYPE.POST , formData);
doRequest(request , callback);
}
private void doRequest(final Request request , final BaseCallback callback){
callback.onRequestBefore();
client.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 {
if (response.isSuccessful()){
String jqury = response.body().string() ;
if (callback.type == String.class){
callback.callBackSucces(response , jqury);
}else {
try{
Object object = gson.fromJson(jqury , callback.type) ;
callbackSuccess(callback , response , jqury);
}catch (Exception e){
callbackError(callback , response , null);
throw new GSON_ANALYZE_MESSAGE_FAILURE("gson解析信息失败") ;
}
}
}else{
callbackError(callback , response , null);
}
}
});
}
private Request buildRequest (String uri , METHOD_TYPE method_type , Map<String , String> formData){
Request.Builder builder = new Request.Builder() ;
if(method_type == METHOD_TYPE.GET){
uri = getUriWithParams(uri , formData) ;
builder.url(uri) ;
builder.get() ;
}else if (method_type == METHOD_TYPE.POST){
builder.url(uri) ;
RequestBody requestBody = buildFormData(formData) ;
builder.post(requestBody) ;
}
return builder.build() ;
}
private RequestBody buildFormData (Map<String , String> formData){
if(formData != null) {
FormEncodingBuilder formEncodingBuilder = new FormEncodingBuilder() ;
for (Map.Entry<String , String> objectMap : formData.entrySet()){
formEncodingBuilder.add( objectMap.getKey() , objectMap.getValue() ) ;
}
return formEncodingBuilder.build() ;
}
return null ;
}
//对参数进行处理
private String getUriWithParams(String uri , Map<String , String > formData){
String symbol = null ;
int signNum = 0 ;
if(formData == null){
return uri ;
}
for(String key : formData.keySet()){
symbol = (signNum++ == 0 )? "?" : "&" ;
uri = uri+symbol+key+"="+formData.get(key) ;
}
return uri ;
}
/**
* 以下方法保证对于okhttp的拦截处理运行在主线程
*
*/
private void callbackTokenError (final BaseCallback baseCallback , final Response response){
handler.post(new Runnable() {
@Override
public void run() {
baseCallback.onTokenError(response , response.code());
}
});
}
private void callbackSuccess (final BaseCallback baseCallback , final Response response , final Object object){
handler.post(new Runnable() {
@Override
public void run() {
try {
baseCallback.callBackSucces(response , object);
} catch (IOException e) {
e.printStackTrace();
}
}
});
}
private void callbackError (final BaseCallback baseCallback , final Response response , final Object object){
handler.post(new Runnable() {
@Override
public void run() {
try {
baseCallback.onErroe(response , response.code() , new GET_RESPONSE_MESSAGE_FAILURE("获取服务器信息失败"));
} catch (IOException e) {
e.printStackTrace();
}
}
});
}
private void callbackFailure (final BaseCallback baseCallback , final Request request , final IOException e){
handler.post(new Runnable() {
@Override
public void run() {
baseCallback.onFailure(request , e);
}
});
}
enum METHOD_TYPE {
GET,
POST
}
private void demo(){
OkHttpClient client = new OkHttpClient() ;
client.setConnectTimeout(5 , TimeUnit.SECONDS);
client.setWriteTimeout(5 , TimeUnit.SECONDS);
client.setReadTimeout(5 , TimeUnit.SECONDS);
String url = "http://www.jianshu.com/p/6ffde18fb034" ;
//盛放参数
RequestBody requestBody = new FormEncodingBuilder()
.add("name","xxx").build() ;
Request request = new Request.Builder().url(url).post(requestBody).build() ;
client.newCall(request).enqueue(new Callback() {
@Override
public void onFailure(Request request, IOException e) {
}
@Override
public void onResponse(Response response) throws IOException {
}
});
}
}
其中BaseCallBack类代码如下:
package com.example.cne_shop.okhttp;
import com.google.gson.internal.$Gson$Types;
import com.squareup.okhttp.Request;
import com.squareup.okhttp.Response;
import java.io.IOException;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
/**
* Created by 博 on 2017/8/22.
*/
public abstract class BaseCallback<T> {
public Type type ;
static Type getSuperclassTypeParameter(Class<?> subclass ){
Type superClass = subclass.getGenericSuperclass() ;
if (superClass instanceof Class){
throw new RuntimeException("Missing type parameter") ;
}
ParameterizedType parameterizedType = (ParameterizedType) superClass;
return $Gson$Types.canonicalize(parameterizedType.getActualTypeArguments()[0]) ;
}
public BaseCallback(){
this.type = getSuperclassTypeParameter(this.getClass()) ;
}
public abstract void onRequestBefore();
public abstract void onFailure(Request request, IOException e) ;
public abstract void onErroe(Response response , int responseCode , Exception e) throws IOException ;
public abstract void callBackSucces(Response response , T t) throws IOException ;
public abstract void onTokenError(Response response , int responseCode );
}
-
有关于getSuperclassTypeParameter()静态方法,作用为取得类泛型的类型。也就是得到T的真实类型。
详细解释戳http://blog.csdn.net/hello__zero/article/details/44201033 -
其中,我们定义了一个OkhttpClient对象,并设置伪静态,使得所有请求都使用这一个对象。
-
利用枚举类型参数,将post与get请求的request构建分别进行操作。得到request类型对象
-
自定义basecallback抽象类,插入Callback的实现方法中中进行实现,使得使用者能在使用时再实现相关的方法,且方法的执行被放在主线程。
使用
- 使用时只需要通过OkhttpHelper.getOkhttpHelper(),方法获得OkhttpHelper对象。
- 使用OkhttpHelper对象调用doget,或dopost方法进行操作。