Retrofit 2.0 + RxJava 2.0搭建简单的Android请求框架。

来源:互联网 发布:数据修复分区图片 编辑:程序博客网 时间:2024/06/05 16:39

      哎,最近智障公司突然学某些公司,搞什么996,然而要搞的项目的需求和UI都还没出来,没事还要蹲到很晚,着实很痛苦哎。。。。之前都没怎么写过博客,正好趁着这段有空的时间来写一遍博客,记录一下自己研究的Rxjava和retrofit一些相关的东西~

      RxJava和Retrofit已经出来很长时间,现在的很多android App都已经被这两个东西占领,现在在弄的这个项目正好就我一个人负责,于是就决定把中东西的老掉牙的网络请求框架给换掉,自己来搭建一个简单的网络请求框架。现在的Rxjava 和 Retrofit 都已经到了2.0,于是自己花了点时间去了解一下它们的1.x和2.x,然后开始搭建自己的网络请求框架。

开始搭建之前,肯定得先引入需要的一些库,gridle 的配置如下:

compile 'io.reactivex.rxjava2:rxandroid:2.0.1'compile 'io.reactivex.rxjava2:rxjava:2.0.1'compile 'com.squareup.retrofit2:retrofit:2.2.0'compile 'com.squareup.retrofit2:converter-gson:2.2.0'compile 'com.jakewharton.retrofit:retrofit2-rxjava2-adapter:1.0.0'
如上图,rxjava、rxandroid和retrofit 全部都是2.x,converter-gson就是json的转换类,最后那个adapter是国外的一个大神弄出来,这个是结合retrofit和rxjava 的关键。

先面先定义一个接口类:

/** * Created by rouzi on 2017/4/7. * 所有接口的入口 */public interface ApiService {    /**     * retrofit2.0登录     * @param loginMap     * @return     */    @POST(UrlConstants.urlHead)    Call<LoginResponse> login(@QueryMap Map<String, String> loginMap);    /**     * retrofit2.0+rxJava2.0 结合登录     * @param loginMap     * @return     */    @POST(UrlConstants.urlHead)    Flowable<LoginResponse> login2(@QueryMap Map<String, String> loginMap);}
定义了两种方式的登录接口,代码上面也都注释,第一个就单纯的用retrofit来调接口,下面这个是两者的结合,retrofit用的这种注解的方式来进行url的设置和传参等,因为项目的请求接口全部是post的、参数以键值对的形式传入,将接口定义成了以上的这种形式。当然,get请求方式直接@Get,参数也支持各种类型@query、@path、@ body等等。

下面定义一个单例:

/** * Created by rouzi on 2017/4/7. *接口管理类 */public class ApiManager {    private ApiService apiService;    private static ApiManager apiManager;    public synchronized static ApiManager getInstance(){        if(apiManager == null){            apiManager = new ApiManager();        }        return apiManager;    }    public ApiService getApiService(){        if(apiService == null){            OkHttpClient okClient = new OkHttpClient.Builder().build();            Retrofit retrofit = new Retrofit.Builder()                    .baseUrl(UrlConstants.baseUrl)                    .client(okClient)                    .addCallAdapterFactory(RxJava2CallAdapterFactory.create())                    .addConverterFactory(GsonConverterFactory.create())                    .build();            apiService = retrofit.create(ApiService.class);        }        return apiService;    }}
上面这个类作为接口的统一入口,在getApiService()方法中,定义了一个OkhttpClent,这个是retrofit强制依赖的
addCallAdapterFactory(RxJava2CallAdapterFactory.create())
这句是讲RxJava和retrofit结合起来。

addConverterFactory(GsonConverterFactory.create())
这个是添加gson解析库,直接对请求结果进行json解析。

下面就可以用起来了:

private void loginRetrofit(){   LoginParam param = new LoginParam();   Call<LoginResponse> call = ApiManager.getInstance().getApiService().login(param);   call.enqueue(new Callback<LoginResponse>() {      @Override      public void onResponse(Call<LoginResponse> call, Response<LoginResponse> response) {         if(!response.body().newLoginResponseMsg.success){            showMessage1(response.body().newLoginResponseMsg.result_code_msg);         }      }      @Override      public void onFailure(Call<LoginResponse> call, Throwable t) {         Log.d("retrofitLoginFailure", t.getMessage());         showMessage1(t.getMessage());      }   });}
上面这种方式只用retrofit的异步调用接口,返回的结果response中,就是直接解析好的结果。

这边有个,就是不管解析成功和失败,都会进入onResponse方法,只不过解析出错了, response为null,所以在这边要进行一些处理。

下面用RxJava 的形式来调用接口:

private void loginFlowable(){   LoginParam param = new LoginParam();   Flowable<LoginResponse> flowable = ApiManager.getInstance().getApiService().login2(param);   flowable.subscribeOn(Schedulers.newThread())         .map(new Function<LoginResponse, LoginResponse>() {            @Override            public LoginResponse apply(LoginResponse loginResponse) throws Exception {               loginResponse.newLoginResponseMsg.result_code_msg = "密码错误,蛤蟆皮";               return loginResponse;            }         })         .observeOn(AndroidSchedulers.mainThread())         .subscribe(new ApiSubscriberCallBack<LoginResponse>() {            @Override            public void onSuccess(LoginResponse loginResponse) {               if(!loginResponse.newLoginResponseMsg.success){                  showMessage1(loginResponse.newLoginResponseMsg.result_code_msg);               }            }            @Override            public void onFailure(Throwable t) {               showMessage1(t.getMessage());            }         });}
在用Rxjava形式调用时,要注意线程切换,耗时的操作肯定不能再主线程,

subscribeOn(Schedulers.newThread)这个方法就是制定被管擦事件在子线程中执行,

observeOn(AndroidSchedulers.mainThread)这个方法让消费事件在主线程进行。

上面的 ApiSubscriberCallBack 类是继承了Subscriber类的:

/** * Created by rouzi on 2017/4/11. * 回调的基类 */public abstract class ApiSubscriberCallBack<T> implements Subscriber<T> {    @Override    public void onSubscribe(Subscription s) {        s.request(Long.MAX_VALUE);    }    @Override    public void onNext(T t) {        onSuccess(t);    }    @Override    public void onError(Throwable t) {        onFailure(t);    }    @Override    public void onComplete() {    }    public abstract void onSuccess(T t);    public abstract void onFailure(Throwable t);}
以为调接口,我们基本是只关注onNext() 和 onError()方法,所以稍微修改一下,改成我们经常用的回调形式:

.subscribe(new ApiSubscriberCallBack<LoginResponse>() {            @Override            public void onSuccess(LoginResponse loginResponse) {               if(!loginResponse.newLoginResponseMsg.success){                  showMessage1(loginResponse.newLoginResponseMsg.result_code_msg);               }            }            @Override            public void onFailure(Throwable t) {               showMessage1(t.getMessage());            }         });
在上面用Rxjava请的过程中,我只用了一个map操作符变换,修改了其中的一个属性,也可以用其它操作符进行别的操作来满足开发中需求。

这个跟上面只用retrofit一样,返回的response如果解析错误,也会返回一个null,所以要注意这个坑。

在我们调试的时候经常需要看接口的请求链接和返回结果的日志,那么就可以在OkHttpClient中设置一个拦截器Interceptor来做这些事情:

class MyInterceptor implements Interceptor {    @Override    public Response intercept(Chain chain) throws IOException {        Request request = chain.request();        Log.d("retrofitRequest", String.format("Sending request %s on %s%n%s",                request.url(), chain.connection(), request.headers()));        Response response = chain.proceed(request);        ResponseBody body = response.peekBody(1024*1024);        String ss = body.string();        Log.d("retrofitResponse", ss);        return response;    }}
先定义一个Interceptor,里面的拿到request,就能进行很多设置,具体不讲解了,然后在okhttpClient中设置一下

OkHttpClient okClient = new OkHttpClient.Builder().addInterceptor(new MyInterceptor()).build();
这样,你就能在Log中,看到你想要的东西了,到这基本就弄完了。

站在巨人的肩膀上,自己也能弄出一个框架(哈哈哈哈哈,这当然离真正的框架差远了,但至少迈出了搭建框架的第一步O(∩_∩)O哈哈~)

Rxjava才刚开始接触没多久,但是觉的这种链式的结构确实写起来很舒服,以后还得多多应用,熟练起来。这确实是个很好用的东西,当然在撸代码的过程中,也不是所有的地方都得使用,具体要不要用还是要根际实际需求来~~~~~~~~~~


7 0