OkHttp与Reftrofit2

来源:互联网 发布:的士打车软件 编辑:程序博客网 时间:2024/05/29 09:25

一.前言

越来越多的人使用okhttp作为自己的网络访问框架,okhttp与Reftrofit的结合也是很多人喜欢用的.本文就OkHttp与Reftrofit2与RxJava的结合使用的小demo介绍这三者的联合使用.

二.okhttp

1.引入库文件

    compile 'com.squareup.okhttp:okhttp:2.4.0'    compile 'com.squareup.okio:okio:1.5.0'

注意:okhttp内部依赖okio,别忘了引入.

2.get请求

其实单纯使用okhttp的网络请求和我们常用的volley等还是挺像的.没什么难度.

//    使用ohhttp访问网络    public void get(String url, Callback callback) {        //创建okHttpClient对象        OkHttpClient mOkHttpClient = new OkHttpClient();        //创建一个Request        Request request = new Request.Builder()                .url(url)                .get()                .build();        //new call        Call call = mOkHttpClient.newCall(request);        //请求加入调度        call.enqueue(callback);    }

调用

        get("http://apis.baidu.com/heweather/pro/attractions", new Callback() {            @Override            public void onFailure(Request request, IOException e) {                CustomToast.showToast(e.toString());            }            @Override            public void onResponse(Response response) throws IOException {                CustomToast.showToast(response.body().string());            }        });

3.post请求

    public void post(String url,Callback callback){        //创建okHttpClient对象        OkHttpClient mOkHttpClient = new OkHttpClient();        FormEncodingBuilder builder = new FormEncodingBuilder();        builder.add("username","king");        Request request = new Request.Builder()                .url(url)                .post(builder.build())                .build();        mOkHttpClient.newCall(request).enqueue(callback);    }

调用

        post("https://github.com/hongyangAndroid", new Callback() {            @Override            public void onFailure(Request request, IOException e) {a                CustomToast.showToast(e.toString());            }            @Override            public void onResponse(Response response) throws IOException {                CustomToast.showToast(response.body().string());            }        });

4.其他

1.这里只介绍okhttp的基础使用,像文件上传下载和对其二次封装就不过多的说了.具体可以看下这篇文章
http://blog.csdn.net/lmj623565791/article/details/47911083

2.这里request请求用了Request.Builder这样一个方法.这其实就是一个建造者模式的应用,我们在使用alert的时候也见过这样的代码

AlertDialog.Builder builder=new AlertDialog.Builder(this);

具体可以看我写的另一篇博客
android常用的设计模式总结

大家翻一下源码很容易看明白的,核心代码就这一点

public final class Request {private Request(Builder builder) {    this.url = builder.url;    this.method = builder.method;    this.headers = builder.headers.build();    this.body = builder.body;    this.tag = builder.tag != null ? builder.tag : this;  }    public Request build() {      if (url == null) throw new IllegalStateException("url == null");      return new Request(this);    }    }

二.reftrofit2

1.介绍

你可以把reftrofit2理解为是一个基于okhttp的网络访问工具类.
和我们常用的工具类不同的是,Retrofit的解耦更彻底:例如通过注解来配置请求参数,根据需求来选择使用不同的CallAdapter(请求适配器,如:RxJava,Java8, Guava)、Converter(反序列化工具,如json, protobuff, xml, moshi)等。

2.基本使用

(1)引入库文件

//retrofit jarcompile 'com.squareup.retrofit2:retrofit:2.0.2'//反序列化json工具compile 'com.squareup.retrofit2:converter-gson:2.0.2'

(2)get请求

先定义一个接口

public interface APIService {    @GET("weather")    Call<Weather> loadeather(@Query("cityname") String cityname,@Query("key") String apiKey);    }

在这里loadeather()方法就是就被标记成了get方法,请求的地址就baseurl+wather.请求参数为cityname和key

看一下调用

    Retrofit retrofit = new Retrofit.Builder().baseUrl(baseUrl)                .addConverterFactory(GsonConverterFactory.create())                .build();        APIService service = retrofit.create(APIService.class);        service.loadeather("杭州", apiKey).enqueue(new Callback<Weather>() {            @Override            public void onResponse(Response<Weather> response, Retrofit retrofit) {                if (response.body() != null) {                    Weather weather = response.body();                    if (weather.getResult() != null) {                         //xxx                    } else {                        tv.setText(weather.getReason());                    }                } else {                    tv.setText("onResponse: body==null");                }            }            @Override            public void onFailure(Throwable t) {                tv.setText(t.toString());            }        });

这里
.addConverterFactory(GsonConverterFactory.create())
这句话就是把返回结果的json转换成了对象

(3)post请求

同样先定义一个接口

public interface APIUserService {    @FormUrlEncoded    @POST("Login")    Call<UserInfo> login(            @Field("userName") String userName,            @Field("password") String password,            @Field("clubId") int clubId,            @Field("leagueId") int leagueId            );}

@FormUrlEncoded代表 表单的方式传递键值对
发送的请求是键值对的形式.

不过我们经常发送的请求是json类型的,怎么发送这样的请求呢?

public interface APIUserService {    @POST("Login")    @Headers({"Content-Type: application/json","Accept: application/json"})//需要添加头    Call<UserInfo> login(@Body RequestBody body);}

发送post请求

      String url = "http://106.75.xx.xx:8080/Api/Front/";        Retrofit retrofit = new Retrofit.Builder().baseUrl(url)                .addConverterFactory(GsonConverterFactory.create())                .build();        APIUserService service = retrofit.create(APIUserService.class);        JSONObject result = new JSONObject();        try {           result.put("userName","admin");           result.put("password","xxxx");           result.put("clubId",1);           result.put("leagueId",2);        } catch (JSONException e) {            e.printStackTrace();        }        HashMap map = new HashMap();        RequestBody body = RequestBody.create(MediaType.parse("application/json"), result.toString());        service.login(body).enqueue(new Callback<UserInfo>() {            @Override            public void onResponse(Response<UserInfo> response, Retrofit retrofit) {                if (response!=null) {                    UserInfo body = response.body();                    tv.setText(body.toString());                }            }            @Override            public void onFailure(Throwable t) {                tv.setText(t.toString());            }        });

设置Interceptor
这个需要简单提一下,很多时候,比如你使用retrofit需要统一的log管理,给每个请求添加统一的header等,这些都应该通过okhttpclient去操作,比如addInterceptor
这里给大家看一个比较全的设置

package com.ethanco.retrofit2_0test;import java.io.File;import java.io.IOException;import java.net.CookieManager;import java.net.CookiePolicy;import java.util.List;import java.util.concurrent.TimeUnit;import okhttp3.Cache;import okhttp3.CacheControl;import okhttp3.Cookie;import okhttp3.CookieJar;import okhttp3.Headers;import okhttp3.HttpUrl;import okhttp3.Interceptor;import okhttp3.OkHttpClient;import okhttp3.Request;import okhttp3.Response;import okhttp3.logging.HttpLoggingInterceptor;import retrofit2.Retrofit;/** * Created by king on 2017/3/26. */public class AppClient {    public static Retrofit retrofit = null;    public static Retrofit retrofit() {        if (retrofit == null) {            OkHttpClient.Builder builder = new OkHttpClient.Builder();            //设置缓存,代码略            setCache(builder);           // 公共参数,代码略            setComent(builder);            // 设置头,代码略            setHeader(builder);           //Log信息拦截器,代码略            setLog(builder);            //设置cookie,代码略            setCookie(builder);            //设置超时和重连,代码略            setConnect(builder);            //以上设置结束,才能build(),不然设置白搭            OkHttpClient okHttpClient = builder.build();            retrofit = new Retrofit.Builder()                    .baseUrl("192.168.1.101")                    .client(okHttpClient)                    .build();        }        return retrofit;    }    private static void setCookie(OkHttpClient.Builder builder) {        /**         * 设置cookie         */        CookieManager cookieManager = new CookieManager();        cookieManager.setCookiePolicy(CookiePolicy.ACCEPT_ALL);        builder.cookieJar(new CookieJar() {            @Override            public void saveFromResponse(HttpUrl url, List<Cookie> cookies) {            }            @Override            public List<Cookie> loadForRequest(HttpUrl url) {                return null;            }        });    }    private static void setHeader(OkHttpClient.Builder builder) {        /**         * 设置头         */        Interceptor headerInterceptor = new Interceptor() {            @Override            public Response intercept(Chain chain) throws IOException {                Request orignaRequest = chain.request();                Request request = orignaRequest.newBuilder()                        .header("AppType", "TPOS")                        .header("Content-Type", "application/json")                        .header("Accept", "application/json")                        .method(orignaRequest.method(), orignaRequest.body())                        .build();                return chain.proceed(request);            }        };        builder.addInterceptor(headerInterceptor);    }    private static void setComent(OkHttpClient.Builder builder) {        /**         * 公共参数         */        Interceptor addQueryParameterInterceptor = new Interceptor() {            @Override            public Response intercept(Chain chain) throws IOException {                Request originalRequest = chain.request();                Request request;                String method = originalRequest.method();                Headers headers = originalRequest.headers();                HttpUrl modifiedUrl = originalRequest.url().newBuilder()                        // Provide your custom parameter here                        .addQueryParameter("platform", "adnroid")                        .addQueryParameter("version", "1.2.0")                        .build();                request = originalRequest.newBuilder().url(modifiedUrl).build();                return chain.proceed(request);            }        };        //公共参数        builder.addInterceptor(addQueryParameterInterceptor);    }    private static void setCache(OkHttpClient.Builder builder) {        final File chachefile = new File(BaseApplication.getContext().getExternalCacheDir(), "HttpCache");        final Cache cache = new Cache(chachefile, 1024 * 1024 * 50);//缓存文件        Interceptor cacheInterceptor = new Interceptor() {            @Override            public Response intercept(Chain chain) throws IOException {                Request request = chain.request();                if (!NetWorkUtils.isNetworkConnected(BaseApplication.getContext())) {                    request = request.newBuilder()                            .cacheControl(CacheControl.FORCE_CACHE)                            .build();                }                Response response = chain.proceed(request);                if (NetWorkUtils.isNetworkConnected (BaseApplication.getContext())) {                    int maxAge = 0;                    // 有网络时 设置缓存超时时间0个小时                    response.newBuilder()                            .header("Cache-Control", "public, max-age=" + maxAge)                            .removeHeader("Pragma")// 清除头信息,因为服务器如果不支持,会返回一些干扰信息,不清除下面无法生效                            .build();                } else {                    //无网络时,设置超时为4周                    int maxStale = 60 * 60 * 24 * 28;                    response.newBuilder()                            .header("Cache-Control", "public, only-if-cached, max-stale=" + maxStale)                            .removeHeader("Pragma")                            .build();                }                return response;            }        };        builder.cache(cache).addInterceptor(cacheInterceptor);    }    public static void setConnect(OkHttpClient.Builder builder) {        /**         * 设置超时和重连         */        //设置超时        builder.connectTimeout(15, TimeUnit.SECONDS);        builder.readTimeout(20, TimeUnit.SECONDS);        builder.writeTimeout(20, TimeUnit.SECONDS);        //错误重连        builder.retryOnConnectionFailure(true);    }    public static void setLog(OkHttpClient.Builder builder) {        /**         * log信息拦截器         */        if (BuildConfig.DEBUG) {            //log信息拦截器            HttpLoggingInterceptor httpLoggingInterceptor = new HttpLoggingInterceptor();            httpLoggingInterceptor.setLevel(HttpLoggingInterceptor.Level.BODY);            //设置Debug Log模式            builder.addInterceptor(httpLoggingInterceptor);        }    }}
0 0
原创粉丝点击