OkHttp使用(一)基本使用

来源:互联网 发布:淘宝店主猝死事件 编辑:程序博客网 时间:2024/05/02 19:26

前言

         OkHttp是一个高效的HTTP库

              Ø  支持 SPDY ,共享同一个Socket来处理同一个服务器的所有请求;

              Ø  如果SPDY不可用,则通过连接池来减少请求延时;

              Ø  无缝的支持GZIP来减少数据流量;

              Ø  缓存响应数据来减少重复的网络请求。

 

l  官网地址

         http://square.github.io/okhttp/

l  Githut地址

         https://github.com/square/okhttp

l  引入依赖

         compile'com.squareup.okhttp3:okhttp:3.2.0'

 

基本使用

         以最新的okhttp3为例。

1.   Http-GET

1)        OkHttpClient:新建一个OkHttpClient实例,用于处理请求。

2)        Request:构建请求参数,如url,请求方式,请求参数,header等。

3)        Call:生成一个具体请求实例,相当于将请求封装成了任务;两种方式:

           ①、call.execute(),非异步方式,会阻塞线程,等待返回结果。

           ②、call.enqueue(Callback),异步方式。

4)      Response:结果响应。

final String url = "http://www.weather.com.cn/data/sk/101010100.html";
//
OkHttpClient okHttpClient = new OkHttpClient();
final okhttp3.Request request = new okhttp3.Request.Builder()
    .url(url)
    .build();
Call call = okHttpClient.newCall(request);       
call.enqueue(new Callback() {
    @Override
    public void onFailure(Call call, IOException e) {
        Log.e(TAG, "onFailure() e=" + e);
    }
    @Override
    public void onResponse(Call call, final Response response) throws IOException {
        Log.i(TAG, " onResponse() reuslt=" + response.body().string());
    }
});

说明:

    ① onResponse回调的参数是response,一般情况下,比如我们希望获得返回的字符串,可以通过response.body().string()获取;如果希望获得返回的二进制字节数组,则调用response.body().bytes();如果你想拿到返回的inputStream,则调用response.body().byteStream()。

    ②  Callback的onFailure()及onResponse()运行在非主线程,不能在该方法中直接进行UI操作。


2.   Http-POST

POST请求跟Get基本相同,需要增加RequestBody来存储请求的参数信息;在Request.Builder中增加post(RequestBody)调用。

RequestBody requestBody = new FormBody.Builder()
.add("key", "value")
    .build();
final okhttp3.Request request = new okhttp3.Request.Builder()
        .url(url)
        .post(requestBody)
        .build();
mOkHttpClient.newCall(request).enqueue(new Callback() {
    @Override
    public void onFailure(Call call, IOException e) {
        Log.e(TAG, "testHttpPost ... onFailure() e=" + e);
    }


    @Override
    public void onResponse(Call call, Response response) throws IOException {
        Log.i(TAG, "testHttpPost ... onResponse() response=" + response.body().string());
    }
});

   有时调试需要查看参数信息,可以通过该方式,获取得到参数信息:

public String getParameters(RequestBody requestBody) {
    try {
        final Buffer buffer = new Buffer();
        requestBody.writeTo(buffer);
        //
        BufferedInputStream bufferedInputStream = new BufferedInputStream(buffer.inputStream());
        final StringBuffer resultBuffer = new StringBuffer();
        byte[] inputBytes = new byte[1024];
        while (true) {
            int count = bufferedInputStream.read(inputBytes);
            if (count <= 0) {
                break;
            }
            resultBuffer.append(new String(Arrays.copyOf(inputBytes, count), Util.UTF_8));
        }
        final String parameter = URLDecoder.decode(resultBuffer.toString(),
                Util.UTF_8.name());
        bufferedInputStream.close();


        return parameter;
    } catch (IOException e) {
        e.printStackTrace();
    } catch (Exception e) {
        e.printStackTrace();
    }
    return null;
}

 

3.   RxJava中使用call.execute()

         call.execute()是阻塞式返回数据方式,可以和RxJava配合使用;关于RxJava使用参看“RxJava使用”部分。

final String url = "http://www.weather.com.cn/data/sk/101010100.html";
//
final okhttp3.Request request = new okhttp3.Request.Builder()
        .url(url)
        .build();
rx.Observable.create(new Observable.OnSubscribe<String>() {
    @Override
    public void call(Subscriber<? super String> subscriber) {
        try {
            //处理请求在IO线程中进行
            final Response response = mOkHttpClient.newCall(request).execute();
            subscriber.onNext(response.body().string());
        }
        catch (IOException e) {
            e.printStackTrace();
            subscriber.onError(e);
        }
    }
})
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Subscriber<String>() {
    @Override
    public void onCompleted() {
    }
    @Override
    public void onError(Throwable e) {
        showInfo(e.toString());
    }
    @Override
    public void onNext(String s) {
        //处理返回结果,在UI线程中,可以直接显示结果
        showInfo(s);
    }
}) ;

    ①  可以通过使用RxJava的map及flatMap过程,直接将json结果转换为具体的数据bean信息(下面以获取天气信息为例,Weatherinfo为自定义的天气信息bean类);具体map及flatMap使用参考“RxJava使用(四)变换”部分。

    ②  该部分需要依赖GSON包。

final String url = "http://www.weather.com.cn/data/sk/101010100.html";
//
rx.Observable.just(url)
        .map(new Func1<String, WeatherinfoResult>() {
            @Override
            public WeatherinfoResult call(String s) {
                final okhttp3.Request request = new okhttp3.Request.Builder()
                        .url(s)
                        .build();
                try {
                    final Response response = mOkHttpClient.newCall(request).execute();
                    //将获取的天气json数据,转换为WeatherinfoResult
                    return JsonUtil.parseData(response.body().string(), WeatherinfoResult.class);
                }
                catch (IOException e) {
                    e.printStackTrace();
                }
                return null;
            }
        })
        .flatMap(new Func1<WeatherinfoResult, Observable<Weatherinfo>>() {
            @Override
            public Observable<Weatherinfo> call(WeatherinfoResult weatherinfoResult) {
                return Observable.just(weatherinfoResult.getWeatherinfo());
            }
        })
        .subscribeOn(Schedulers.io())
        .observeOn(AndroidSchedulers.mainThread())
        .subscribe(new Subscriber<Weatherinfo>() {
            @Override
            public void onCompleted() {
            }
            @Override
            public void onError(Throwable e) {
                showInfo("error:" + e.toString());
            }
            @Override
            public void onNext(Weatherinfo s) {
                showInfo(s.toString());
            }
        }) ;

0 0
原创粉丝点击