1. 程式人生 > >Android 一個改善的okHttp封裝庫

Android 一個改善的okHttp封裝庫

概述 使用 封裝 流程 ews etc 服務器 ... 進度

轉載請標明出處:
http://blog.csdn.net/lmj623565791/article/details/49734867;
本文出自:【張鴻洋的博客】

一、概述

之前寫了篇Android OkHttp全然解析 是時候來了解OkHttp了,事實上主要是作為okhttp的普及文章,當然裏面也簡單封裝了工具類,沒想到關註和使用的人還挺多的,因為這股熱情,該工具類中的方法也是劇增,各種重載方法,以致於使用起來極不方便。實在羞愧。

於是,在這個周末,抽點時間對該工具類,進行了又一次的拆解與編寫。順便完好下功能,盡可能的提升其使用起來的方便性和易擴展性。

標題的改善,也是指的是對於我之前的代碼進行改善。

假設你對okhttp不了解,能夠通過Android OkHttp全然解析 是時候來了解OkHttp了進行了解。

ok。那麽眼下,該封裝庫誌支持:

  • 一般的get請求
  • 一般的post請求
  • 基於Http的文件上傳
  • 文件下載
  • 上傳下載的進度回調
  • 載入圖片
  • 支持請求回調。直接返回對象、對象集合
  • 支持session的保持
  • 支持自簽名站點https的訪問,提供方法設置下證書就可以
  • 支持取消某個請求

源代碼地址:https://github.com/hongyangAndroid/okhttp-utils


引入:

  • Android Studio

    使用前。對於Android Studio的用戶。能夠選擇加入:

    compile project(‘:okhttputils‘)

    或者

    compile ‘com.zhy:okhttputils:2.0.0‘
  • Eclipse

    自行copy源代碼。

二、基本使用方法

眼下基本的使用方法格式為:

OkHttpUtils
    .get()
    .url(url)
    .addParams("username", "hyman")
    .addParams("password", "123")
    .build()
    .execute(callback);

通過鏈式去依據自己的須要加入各種參數,最後調用execute(callback)進行運行,傳入callback則代表是異步。假設單純的execute()則代表同步的方法調用。

能夠看到,取消了之前一堆的get重載方法。參數也能夠進行靈活的選擇了。

以下簡單看一下,全部的使用方法:

(1)GET請求

String url = "http://www.csdn.net/";
OkHttpUtils
    .get()
    .url(url)
    .addParams("username", "hyman")
    .addParams("password", "123")
    .build()
    .execute(new StringCallback()
            {
                @Override
                public void onError(Request request, Exception e)
                {

                }

                @Override
                public void onResponse(String response)
                {

                }
            });

(2)POST請求

 OkHttpUtils
    .post()
    .url(url)
    .addParams("username", "hyman")
    .addParams("password", "123")
    .build()
    .execute(callback);

(3)Post String

OkHttpUtils
    .postString()
    .url(url)
    .content(new Gson().toJson(new User("zhy", "123")))
    .build()
    .execute(new MyStringCallback());   

將string作為請求體傳入到服務端,比如json字符串。

(4)Post File

OkHttpUtils
    .postFile()
    .url(url)
    .file(file)
    .build()
    .execute(new MyStringCallback());

將file作為請求體傳入到服務端.

(5)基於POST的文件上傳(相似web上的表單)

OkHttpUtils.post()//
    .addFile("mFile", "messenger_01.png", file)//
    .addFile("mFile", "test1.txt", file2)//
    .url(url)
    .params(params)//
    .headers(headers)//
    .build()//
    .execute(new MyStringCallback());

(6)下載文件

OkHttpUtils//
    .get()//
    .url(url)//
    .build()//
    .execute(new FileCallBack(Environment.getExternalStorageDirectory().getAbsolutePath(), "gson-2.2.1.jar")//
    {
        @Override
        public void inProgress(float progress)
        {
            mProgressBar.setProgress((int) (100 * progress));
        }

        @Override
        public void onError(Request request, Exception e)
        {
            Log.e(TAG, "onError :" + e.getMessage());
        }

        @Override
        public void onResponse(File file)
        {
            Log.e(TAG, "onResponse :" + file.getAbsolutePath());
        }
    });

(7)顯示圖片

OkHttpUtils
    .get()//
    .url(url)//
    .build()//
    .execute(new BitmapCallback()
    {
        @Override
        public void onError(Request request, Exception e)
        {
            mTv.setText("onError:" + e.getMessage());
        }

        @Override
        public void onResponse(Bitmap bitmap)
        {
            mImageView.setImageBitmap(bitmap);
        }
    });

哈,眼下來看。清晰多了。

三、對於上傳下載的回調

new Callback<?>()
{
    //...
    @Override
    public void inProgress(float progress)
    {
       //use progress: 0 ~ 1
    }
}

對於傳入的callback有個inProgress方法,須要拿到進度直接復寫該方法就可以。

四、對於自己主動解析為實體類

眼下去除了Gson的依賴,提供了自己定義Callback的方式,讓用戶自己去解析返回的數據,眼下提供了StringCallbackFileCallback,BitmapCallback 分別用於返回string。文件下載,載入圖片。

當然假設你希望解析為對象,你能夠:

public abstract class UserCallback extends Callback<User>
{
    //非UI線程,支持不論什麽耗時操作
    @Override
    public User parseNetworkResponse(Response response) throws IOException
    {
        String string = response.body().string();
        User user = new Gson().fromJson(string, User.class);
        return user;
    }
}

自己使用自己喜歡的Json解析庫完畢就可以。

解析成List<User>,則例如以下:

public abstract class ListUserCallback extends Callback<List<User>>
{
    @Override
    public List<User> parseNetworkResponse(Response response) throws IOException
    {
        String string = response.body().string();
        List<User> user = new Gson().fromJson(string, List.class);
        return user;
    }


}

五、對於https單向認證

很easy,拿到xxx.cert的證書。

然後調用


OkHttpUtils.getInstance()
        .setCertificates(inputstream);

建議使用方式,比如我的證書放在assets文件夾:


/**
 * Created by zhy on 15/8/25.
 */
public class MyApplication extends Application
{
    @Override
    public void onCreate()
    {
        super.onCreate();

        try
        {    
        OkHttpUtils
         .getInstance()
         .setCertificates(getAssets().open("aaa.cer"),
 getAssets().open("server.cer"));
        } catch (IOException e)
        {
            e.printStackTrace();
        }
    }
}

就可以。別忘了註冊Application。

註意:假設https站點為權威機構頒發的證書,不須要以上設置。自簽名的證書才須要。

六、配置

(1)全局配置

能夠在Application中。通過:

OkHttpClient client = 
OkHttpUtils.getInstance().getOkHttpClient();

然後調用client的各種set方法。

比如:

client.setConnectTimeout(100000, TimeUnit.MILLISECONDS);

(2)為單個請求設置超時

比方涉及到文件的須要設置讀寫等待時間多一點。

 OkHttpUtils
    .get()//
    .url(url)//
    .tag(this)//
    .build()//
    .connTimeOut(20000)
    .readTimeOut(20000)
    .writeTimeOut(20000)
    .execute()

調用build()之後。能夠隨即設置各種timeOut.

(3)取消單個請求

 RequestCall call = OkHttpUtils.get().url(url).build();
 call.cancel();

(4)依據tag取消請求

眼下對於支持的方法都加入了最後一個參數Object tag,取消則通過OkHttpUtils.cancelTag(tag)運行。

比如:在Activity中,當Activity銷毀取消請求:

OkHttpUtils
    .get()//
    .url(url)//
    .tag(this)//
    .build()//

@Override
protected void onDestroy()
{
    super.onDestroy();
    //能夠取消同一個tag的
    OkHttpUtils.cancelTag(this);//取消以Activity.this作為tag的請求
}

比方,當前Activity頁面全部的請求以Activity對象作為tag。能夠在onDestory裏面統一取消。

七、淺談封裝

事實上整個封裝的過程比較簡單,這裏簡單描寫敘述下,對於okhttp一個請求的流程大致是這種:

//創建okHttpClient對象
OkHttpClient mOkHttpClient = new OkHttpClient();
//創建一個Request
final Request request = new Request.Builder()
                .url("https://github.com/hongyangAndroid")
                .build();
//new call
Call call = mOkHttpClient.newCall(request); 
//請求加入調度
call.enqueue(new Callback()
{
    @Override
    public void onFailure(Request request, IOException e)
    {
    }

    @Override
    public void onResponse(final Response response) throws IOException
    {
            //String htmlStr =  response.body().string();
    }
});             

當中基本的差異,事實上就是request的構建過程。

我對Request抽象了一個類:OkHttpRequest

public abstract class OkHttpRequest
{
    protected RequestBody requestBody;
    protected Request request;

    protected String url;
    protected String tag;
    protected Map<String, String> params;
    protected Map<String, String> headers;

    protected OkHttpRequest(String url, String tag,
                            Map<String, String> params, Map<String, String> headers)
    {
        this.url = url;
        this.tag = tag;
        this.params = params;
        this.headers = headers;
    }

    protected abstract Request buildRequest();
    protected abstract RequestBody buildRequestBody();

    protected void prepareInvoked(ResultCallback callback)
    {
        requestBody = buildRequestBody();
        requestBody = wrapRequestBody(requestBody, callback);
        request = buildRequest();
    }

    protected RequestBody wrapRequestBody(RequestBody requestBody, final ResultCallback callback)
    {
        return requestBody;
    }


    public void invokeAsyn(ResultCallback callback)
    {
        prepareInvoked(callback);
        mOkHttpClientManager.execute(request, callback);
    }


     // other common methods
 }   

一個request的構建呢,我分三個步驟:buildRequestBody , wrapRequestBody ,buildRequest這種次序,當以上三個方法沒有問題時,我們就拿到了request。然後運行就可以。

可是對於不同的請求。requestBody以及request的構建過程是不同的。所以大家能夠看到buildRequestBody ,buildRequest為抽象的方法,也就是不同的請求類。比方OkHttpGetRequestOkHttpPostRequest等須要自己去構建自己的request。

對於wrapRequestBody方法呢,能夠看到它默認基本屬於空實現,主要是因為並不是全部的請求類都須要復寫它,僅僅有上傳的時候呢,須要回調進度。須要對requestBody進行包裝。所以這種方法相似於一個鉤子。

事實上這個過程有點相似模板方法模式,有興趣能夠看看一個短篇介紹設計模式 模版方法模式 展現程序猿的一天 .

對於更加具體的使用方法,能夠查看github上面的readme。以及demo,眼下demo包括:

技術分享

對於上傳文件的兩個button,須要自己搭建服務器。其它的button能夠直接測試。

最後,因為本人水平有限。以及時間比較倉促~~發現問題,歡迎提issue,我會抽時間解決。 have a nice day ~

源代碼點擊下載


歡迎關註我的微博:
http://weibo.com/u/3165018720


群號:514447580,歡迎入群

微信公眾號:hongyangAndroid
(歡迎關註,第一時間推送博文信息)
技術分享

Android 一個改善的okHttp封裝庫