初探Okhttp3+Retrofit2+RXJava

本文介绍了作者作为Android开发者,在面对Android 6.0后HTTP框架的变化,如何转向使用Okhttp3+Retrofit2+RXJava这一流行组合。文章详细描述了如何在Gradle中添加相关依赖,并提及了这些库采用的Builder设计模式,以及Okhttp的高性能特性。
摘要由CSDN通过智能技术生成

初探Okhttp3+Retrofit2+RXJava

           本人菜鸟一枚,涉及Android开发也只有区区两年的时间,联网操作从最初接触的httpClient到Xutils,因为后来Android6.0发布。使得联网操作有了很大的变化。Android 6.0发布之后,谷歌已经将所有旧版的HttpURLConnection,HttpClient,和一些和apache有关包的类和方法定义为过时方法,并且Android SDK 23之后不再内置旧版的类和接口,需要额外引用jar包,为了代码的健壮性也需要抛弃旧版Android的HTTP框架。

    后来听说Okhttp3+Retrofit2+RXJava这个东西真的挺火的,所以找个时间,初步探索了一下这个框架,从网上找到了不少素材、资料、源码以及大神们的分享经验。不得不说,这个时代,网络真的很神奇,近乎无所不能。废话不多说,开始正经上代码。

    Android studio 首先在gradle里添加引用,这里一共会添加7个包的引用

    

    前两个包是rxjava所能够用到的,第三个是okhttp3的引用包,四五六这三个包是retrofit2的引用包,其中还包含了默认的gson解析,以方便使用,最后一个包是OKhttp3日志拦截引用包。

public abstract class RetrofitUtils {

    //服务器路径
    private static final String API_SERVER = Constants.URL.URL;
    private static Retrofit mRetrofit;
    private static OkHttpClient mOkHttpClient;

    /**
     * 获取Retrofit对象
     *
     * @return
     */
    protected static Retrofit getRetrofit() {

        if (null == mRetrofit) {
            if (null == mOkHttpClient) {
                mOkHttpClient = OkHttp3Utils.getOkHttpClient();
            }
            //Retrofit2后使用build设计模式
            mRetrofit = new Retrofit.Builder()
                    //设置服务器路径
                    .baseUrl(API_SERVER + "/")
                    //添加转化库,默认是Gson
                    .addConverterFactory(GsonConverterFactory.create())
                    //添加回调库,采用RxJava
                    .addCallAdapterFactory(RxJavaCallAdapterFactory.create())
                    //设置使用okhttp网络请求
                    .client(mOkHttpClient)
                    .build();
        }
        return mRetrofit;
    }
}

    

    从Retrofit升级到2.0之后,就使用了build设计模式(生产者模式),将一个复杂的构建与其表示相分离。

    baseUrl(API_SERVER + “/”):设置服务器路径
    addConverterFactory(GsonConverterFactory.create()):添加转化库,默认是Gson
    addCallAdapterFactory(RxJavaCallAdapterFactory.create()):添加回调库,采用RxJava
    client(mOkHttpClient):设置使用okhttp网络请求

最后是设置okhttp为网络请求,okhttp是高性能的http库,拥有队列线程池,轻松解决并发,自动维护socket连接池,所以这里使用okhttp可谓是更上一层楼。    

/**
     * 获取OkHttpClient对象
     *
     * @return
     */
    public static OkHttpClient getOkHttpClient() {

        if (null == mOkHttpClient) {

            //同样okhttp3后也使用build设计模式
            mOkHttpClient = new OkHttpClient.Builder()
                    //设置一个自动管理cookies的管理器
                    .cookieJar(new CookiesManager())
                    //添加拦截器
                    //.addInterceptor(new MyIntercepter())
                    //添加网络连接器
                    //.addNetworkInterceptor(new CookiesInterceptor(MyApplication.getInstance().getApplicationContext()))
                    //设置请求读写的超时时间
                    .connectTimeout(30, TimeUnit.SECONDS)
                    .writeTimeout(30, TimeUnit.SECONDS)
                    .readTimeout(30, TimeUnit.SECONDS)
                    .cache(cache)
                    .build();
        }

        return mOkHttpClient;
    }

    同样升级到okhttp3后,也使用build设计模式。

public interface NetService {
    /**
     * 常用的注解:
     *
     * @GET GET请求方式
     * @POST POST请求方式
     * @Query GET请求参数
     * @Header 用来添加Header请求头
     * @FormUrlEncoded post请求头标示
     * <p>
     * 其他注解请求方式:
     * @PUT 表示这是一个PUT请求
     * @DELETE 表示这是一个DELETE请求
     * @HEAD 表示这是一个HEAD请求
     * @OPTIONS 表示这是一个OPTION请求
     * @PATCH 表示这是一个PAT请求
     */

    //设缓存有效期为1天
    long CACHE_STALE_SEC = 60 * 60 * 24 * 1;
    //查询缓存的Cache-Control设置,使用缓存
    String CACHE_CONTROL_CACHE = "only-if-cached, max-stale=" + CACHE_STALE_SEC;
    //查询网络的Cache-Control设置。不使用缓存
    String CACHE_CONTROL_NETWORK = "max-age=0";

    //POST请求
    @FormUrlEncoded
    @POST("/a/login")
    Observable<Verification> getVerificationCodePost(@Field("__ajax") String __ajax, @Field("username") String username, @Field("password") String password, @Field("mobileLogin") String mobileLogin);

    //POST请求
    @FormUrlEncoded
    @POST("/a/login")
    Observable<Verification> getVerificationCodePostMap(@FieldMap Map<String, String> map);

    //GET请求
    @GET("/a/login")
    Observable<Verification> getVerificationGet(@Field("__ajax") String __ajax, @Field("username") String username, @Field("password") String password, @Field("mobileLogin") String mobileLogin);

    //GET请求,设置缓存
    @Headers("Cache-Control: public," + CACHE_CONTROL_CACHE)
    @GET("/a/login")
    Observable<Verification> getVerificationGetCache(@Field("__ajax") String __ajax, @Field("username") String username, @Field("password") String password, @Field("mobileLogin") String mobileLogin);

    @Headers("Cache-Control: public," + CACHE_CONTROL_NETWORK)
    @GET("/a/login")
    Observable<MenuBean> getMainMenu();

}

    cookieJar(new CookiesManager()): 设置一个自动管理cookies的管理器 
   addInterceptor(new MyIntercepter()):添加拦截器 addNetworkInterceptor(new    CookiesInterceptor(MyApplication.getInstance().getApplicationContext())):添加网络连接器 
   connectTimeout(30, TimeUnit.SECONDS):请求超时时间 writeTimeout(30,    TimeUnit.SECONDS):写入超时时间 readTimeout(30, TimeUnit.SECONDS):读取超时时间

        将NetService写成一个单独的接口,里面包含的是各个不同联网接口的调用,post,get,put,head等等。这样可以方便后面调用工具类的调用。

public class NetWorks extends RetrofitUtils {

    private static final NetService service = getRetrofit().create(NetService.class);

    //POST请求
    public static void verificationCodePost(String __ajax, String username, String password, String mobileLogin, Observer<Verification> observer) {
        setSubscribe(service.getVerificationCodePost(__ajax, username, password, mobileLogin), observer);
    }

    //POST请求参数以map传入
    public static void verificationCodePostMap(Map<String, String> map, Observer<Verification> observer) {
        setSubscribe(service.getVerificationCodePostMap(map), observer);
    }

    //Get请求设置缓存
    public static void verificationCodeGetCache(String __ajax, String username, String password, String mobileLogin, Observer<Verification> observer) {
        setSubscribe(service.getVerificationGetCache(__ajax, username, password, mobileLogin), observer);
    }

    //Get请求
    public static void verificationCodeGet(String __ajax, String username, String password, String mobileLogin, Observer<Verification> observer) {
        setSubscribe(service.getVerificationGet(__ajax, username, password, mobileLogin), observer);
    }

    //Get请求
    public static void verificationCodeGetsub(String __ajax, String username, String password, String mobileLogin, Observer<Verification> observer) {
        setSubscribe(service.getVerificationGet(__ajax, username, password, mobileLogin), observer);
    }

    //Get请求
    public static void GetCache(Observer<MenuBean> observer) {
        setSubscribe(service.getMainMenu(), observer);
    }

    /**
     * 插入观察者
     *
     * @param observable
     * @param observer
     * @param <T>
     */
    private static <T> void setSubscribe(Observable<T> observable, Observer<T> observer) {
        observable.subscribeOn(Schedulers.io())
                .subscribeOn(Schedulers.newThread())//子线程访问网络
                .observeOn(AndroidSchedulers.mainThread())//回调到主线程
                .subscribe(observer);
    }
}



    setSubscribe方法其实就是插入观察者。通过NetWorks来进行接口NetService的调用。

    下面就是最后一步了,一起来看看吧。

public class MainActivity extends AppCompatActivity {
    private TextView mTv, mTv2, mTv3;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        mTv = (TextView) findViewById(R.id.main_tv);
        mTv2 = (TextView) findViewById(R.id.main_tv2);
        mTv3 = (TextView) findViewById(R.id.main_tv3);

        NetWorks.verificationCodePost("true", "xinshuju01", "111111", "true", new Observer<Verification>() {
            @Override
            public void onCompleted() {
                //完成
            }

            @Override
            public void onError(Throwable e) {
                //异常
                mTv.setText(e.getLocalizedMessage());
                Log.e("MAIN2", e.getLocalizedMessage() + "--" + e.getMessage());
            }

            @Override
            public void onNext(Verification verification) {
                //成功
                mTv.setText(verification.getUser().toString());
            }
        });

        Map<String, String> map = new HashMap<>();
        map.put("__ajax", "true");
        map.put("username", "xinshuju01");
        map.put("password", "111111");
        map.put("mobileLogin", "true");

        NetWorks.verificationCodePostMap(map, new Observer<Verification>() {
            @Override
            public void onCompleted() {
                //完成
            }

            @Override
            public void onError(Throwable e) {
                //异常
                mTv2.setText(e.getLocalizedMessage());
                Log.e("MAIN2", e.getLocalizedMessage() + "--" + e.getMessage());
            }

            @Override
            public void onNext(Verification verification) {
                //成功
                mTv2.setText(verification.getUser().toString());
            }
        });

        NetWorks.GetCache(new Observer<MenuBean>() {
            @Override
            public void onCompleted() {
                //完成
            }

            @Override
            public void onError(Throwable e) {
                //异常
                mTv3.setText(e.getLocalizedMessage());
                Log.e("MAIN2", e.getLocalizedMessage() + "--" + e.getMessage());
            }

            @Override
            public void onNext(MenuBean baseBean) {
                //成功
                mTv3.setText(baseBean.toString());
            }
        });
    }
}
    这样在Activity中引用也是很方便的,直接调用就可以了,只需要把参数还有观察者罗列一下或者是把map和观察者传递到方法里面就可以直接调用了。成功会返回你所需要的bean对象,如果是失败了,会返回对应的错误信息,像404,405,等有机会试一下403,本人公司项目经常会出现403的问题。

主要还是感谢大神。参考博客:http://blog.csdn.net/wlt111111/article/details/51455524

如果有什么好的意见,建议或者我有什么bug,欢迎评论联系。




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值