仿京東商城系列3------封裝Okhttp

本項目來自菜鳥窩阿蝶,有興趣者點擊http://www.cniao5.com/course/

項目已經做完,源碼地址蔫巩。https://github.com/15829238397/CN5E-shop

仿京東商城系列0------項目簡介
仿京東商城系列1------fragmentTabHost實現(xiàn)底部導航欄
仿京東商城系列2------自定義toolbar
仿京東商城系列3------封裝Okhttp
仿京東商城系列4------輪播廣告條
仿京東商城系列5------商品推薦欄
仿京東商城系列6------下拉刷新上拉加載的商品列表
仿京東商城系列7------商品分類頁面
仿京東商城系列8------自定義的數量控制器
仿京東商城系列9------購物車數據存儲器實現(xiàn)
仿京東商城系列10------添加購物車,管理購物車功能實現(xiàn)
仿京東商城系列11------商品排序功能以及布局切換實現(xiàn)(Tablayout)
仿京東商城系列12------商品詳細信息展示(nativie與html交互)
仿京東商城系列13------商品分享(shareSDK)
仿京東商城系列14------用戶登錄以及app登錄攔截
仿京東長城系列15------用戶注冊,SMSSDK集成
仿京東商城系列16------支付SDK集成
仿京東商城系列17------支付功能實現(xiàn)
仿京東商城系列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.reibang.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.reibang.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() ;
    }

    //提供一個靜態(tài)方法供外部請求推溃。
    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.reibang.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ài)方法届腐,作用為取得類泛型的類型铁坎。也就是得到T的真實類型。
    詳細解釋戳http://blog.csdn.net/hello__zero/article/details/44201033

  • 其中犁苏,我們定義了一個OkhttpClient對象硬萍,并設置偽靜態(tài),使得所有請求都使用這一個對象围详。

  • 利用枚舉類型參數朴乖,將post與get請求的request構建分別進行操作。得到request類型對象

  • 自定義basecallback抽象類助赞,插入Callback的實現(xiàn)方法中中進行實現(xiàn)买羞,使得使用者能在使用時再實現(xiàn)相關的方法,且方法的執(zhí)行被放在主線程雹食。

使用

  • 使用時只需要通過OkhttpHelper.getOkhttpHelper(),方法獲得OkhttpHelper對象畜普。
  • 使用OkhttpHelper對象調用doget,或dopost方法進行操作群叶。
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末吃挑,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子街立,更是在濱河造成了極大的恐慌舶衬,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,402評論 6 499
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件赎离,死亡現(xiàn)場離奇詭異约炎,居然都是意外死亡,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,377評論 3 392
  • 文/潘曉璐 我一進店門圾浅,熙熙樓的掌柜王于貴愁眉苦臉地迎上來掠手,“玉大人,你說我怎么就攤上這事狸捕∨绺耄” “怎么了?”我有些...
    開封第一講書人閱讀 162,483評論 0 353
  • 文/不壞的土叔 我叫張陵灸拍,是天一觀的道長做祝。 經常有香客問我,道長鸡岗,這世上最難降的妖魔是什么混槐? 我笑而不...
    開封第一講書人閱讀 58,165評論 1 292
  • 正文 為了忘掉前任,我火速辦了婚禮轩性,結果婚禮上声登,老公的妹妹穿的比我還像新娘。我一直安慰自己揣苏,他們只是感情好悯嗓,可當我...
    茶點故事閱讀 67,176評論 6 388
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著卸察,像睡著了一般脯厨。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上坑质,一...
    開封第一講書人閱讀 51,146評論 1 297
  • 那天合武,我揣著相機與錄音,去河邊找鬼涡扼。 笑死眯杏,一個胖子當著我的面吹牛,可吹牛的內容都是我干的壳澳。 我是一名探鬼主播,決...
    沈念sama閱讀 40,032評論 3 417
  • 文/蒼蘭香墨 我猛地睜開眼茫经,長吁一口氣:“原來是場噩夢啊……” “哼巷波!你這毒婦竟也來了?” 一聲冷哼從身側響起卸伞,我...
    開封第一講書人閱讀 38,896評論 0 274
  • 序言:老撾萬榮一對情侶失蹤抹镊,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后荤傲,有當地人在樹林里發(fā)現(xiàn)了一具尸體垮耳,經...
    沈念sama閱讀 45,311評論 1 310
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 37,536評論 2 332
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了终佛。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片俊嗽。...
    茶點故事閱讀 39,696評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖铃彰,靈堂內的尸體忽然破棺而出绍豁,到底是詐尸還是另有隱情,我是刑警寧澤牙捉,帶...
    沈念sama閱讀 35,413評論 5 343
  • 正文 年R本政府宣布竹揍,位于F島的核電站,受9級特大地震影響邪铲,放射性物質發(fā)生泄漏芬位。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,008評論 3 325
  • 文/蒙蒙 一带到、第九天 我趴在偏房一處隱蔽的房頂上張望昧碉。 院中可真熱鬧,春花似錦阴孟、人聲如沸晌纫。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,659評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽锹漱。三九已至,卻和暖如春慕嚷,著一層夾襖步出監(jiān)牢的瞬間哥牍,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,815評論 1 269
  • 我被黑心中介騙來泰國打工喝检, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留嗅辣,地道東北人。 一個月前我還...
    沈念sama閱讀 47,698評論 2 368
  • 正文 我出身青樓挠说,卻偏偏與公主長得像澡谭,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子损俭,可洞房花燭夜當晚...
    茶點故事閱讀 44,592評論 2 353

推薦閱讀更多精彩內容