RxJava和Retrofit结合使用

首先分别对RxJava和Retrofit做一个简单的讲解,让大家有一个初步的印象。

 RxJava的最大作用就是异步操作,在很多时候我们需要在不同的线程中来进行操作,最明显的就是加载网络数据然后刷新界面。因为访问网络是耗时的操作,相信大家都回知道要放在子线程里面去做,刷新界面就肯定在主线程里面操作了,这个已经是简单到不能再简单的了。很多人可能会用AsyncTask和Handler和操作,这是完全没有问题的,只是用过的朋友都会知道它只能是一个程序块的执行,在AsyncTask执行完以后又要把块数据传递给handler再去处理,这样,当你过了一段时间再去看你的代码的时候你就会发现修改起来真的是麻烦至极而且是头疼。而ReJava的执行是链式的执行操作,它把任务的执行按照链式的模式来处理,使用的是观察者模式,待会下面再讲。不仅如此,它还可以按需的指定任务执行的线程,这个真的是屌屌的。想详细的对ReJava进行学习的同学可以去看看这位大神的文章:http://gank.io/post/560e15be2dca930e00da1083


ReJava采用的是观察者模式,看一个简单的例子:Button执行监听事件setOnclickListener(OnclickListener)后会执行onclick() 方法,ReJava模式中的观察者模式其实跟这个差不多,Observable是被观察者,Observer或者是Subscriber是观察者,他们通过subscrib()来进行订阅:Observable.subscrib(Subscriber)。Subscriber会处理Observable触发的事件。先看看ReJava的代码模式

 Observable.create(new Observable.OnSubscribe<Drawable>() {
                    @Override
                    public void call(Subscriber<? super Drawable> subscriber) {
                        Drawable drawable=getResources().getDrawable(drawableRes);
                        subscriber.onNext(drawable);
                        subscriber.onCompleted();

                    }
                }).subscribeOn(Schedulers.io())
                        .observeOn(AndroidSchedulers.mainThread())
                        .subscribe(new Observer<Drawable>() {
                            @Override
                            public void onCompleted() {
                                Intent intent = new Intent(TwoActivity.this, ThreeActivity.class);
                                startActivity(intent);
                                finish();
                            }

                            @Override
                            public void onError(Throwable e) {

                            }

                            @Override
                            public void onNext(Drawable drawable) {
                                img_view.setImageDrawable(drawable);
                            }
                        });
ReJava的使用这里我们选择是关联远程库的模式:
compile 'io.reactivex:rxjava:1.0.14'
compile 'io.reactivex:rxandroid:1.0.1'


Retrofit其实就是一个网络数据加载的库,在这里附上github的地址,大家可以先去看看http://square.github.io/retrofit/

Retrofit的使用有两种方法,详细看下面的图片,图片来源Retrofit官网。


下面将以一个小例子的形式演示它们的使用。

第一步:我们先要把需要的技术点罗列出来。

A:实现不同activity和framgent之间通讯的框架,这里我们用Eventbus 

B:ReJava的远程库》

compile 'io.reactivex:rxjava:1.0.14'
compile 'io.reactivex:rxandroid:1.0.1'
C:Retrofit的关联远程库》
compile 'com.squareup.retrofit2:retrofit:2.0.0'
D:因为Retrofit内部会自动转换为我们需要的bean,所以还需要转换gson库》
compile 'com.squareup.retrofit2:converter-gson:2.0.0'
E:因为是ReJava和Retrofit配套使用,当网络请求完毕以Rejava的形式返回数据,没有这个的话会报错》
compile 'com.squareup.retrofit2:adapter-rxjava:2.0.0'
F:涉及到网络请求,http肯定就少不了了》
compile 'com.squareup.okhttp3:okhttp:3.2.0'
G:图片的加载库》
compile 'com.github.bumptech.glide:glide:3.7.0'
H:注解类》
compile 'com.jakewharton:butterknife:7.0.1'
compile 'com.jakewharton.rxbinding:rxbinding:0.4.0'



第二步:创建网络接口
/**
 * Created by AHuan 2016/8/12 0012.
 */
public interface LoginApi {
   /* //第一种方法
    @POST("member/login")
    Call<LoginBean> loginIn(@Body RequestBody body);*/

    //第二种方法
    @POST("member/login")
    Observable<LoginBean> loginIn(@Body RequestBody body);
}
/**
 * Created by AHuan on 2016/8/15 0015.
 */
public interface HealthRecordApi {
    @GET("health")
    Observable<HealthRecordBean> getHealthRecord(@Query("member_id") String member_id,@Query("page") String page,@Query("number") String number);

}

第三步:创建网络请求
/**
 * Created by AHuan on 2016/8/12 0012.
 */
public class NetWork {
    private static LoginApi loginApi;
    private static HealthRecordApi healthRecordApi;
    private static OkHttpClient okHttpClient = new OkHttpClient.Builder()
            .addInterceptor(new BaseParamsInterceptor()).build();
    private static Converter.Factory gsonConverterFactory = GsonConverterFactory.create();
    private static CallAdapter.Factory rxJavaCallAdapterFactory = RxJavaCallAdapterFactory.create();

    public static LoginApi getLoginApi(){
        if(loginApi==null){
            Retrofit retrofit= new Retrofit.Builder()
                    .client(okHttpClient)
                    .baseUrl("http://120.24.65.96/api/")
                    .addConverterFactory(gsonConverterFactory)
                    .addCallAdapterFactory(rxJavaCallAdapterFactory)//这一行是RxJava的转换器,如果api回调的不是Observable<LoginBean>被观察者,那么这一行可以注释
                    .build();
            loginApi=retrofit.create(LoginApi.class);
        }
        return loginApi;
    }

    public static HealthRecordApi getHealthRecordApi(){
        if(healthRecordApi==null){
            Retrofit retrofit= new Retrofit.Builder()
                    .client(okHttpClient)
                    .baseUrl("http://120.24.65.96/api/")
                    .addConverterFactory(gsonConverterFactory)
                    .addCallAdapterFactory(rxJavaCallAdapterFactory)//这一行是RxJava的转换器,如果api回调的不是Observable<LoginBean>被观察者,那么这一行可以注释
                    .build();
            healthRecordApi=retrofit.create(HealthRecordApi.class);
        }
        return healthRecordApi;
    }


    /**
     * 创建拦截器
     */
     //这里用于在HTTP头部添加一些拦截信息,例如token和IMEI码之类的
    public static class BaseParamsInterceptor implements Interceptor{

        @Override
        public Response intercept(Chain chain) throws IOException {
            Request.Builder requestBuilder=chain.request().newBuilder();
            Iterator iterator = UIUtil.getHeaderMap().entrySet().iterator();
            while (iterator.hasNext()) {
                Map.Entry entry = (Map.Entry) iterator.next();
                requestBuilder.addHeader((String) entry.getKey(), (String) entry.getValue());
            }
            return chain.proceed(requestBuilder.build());
        }
    }
}

第四步:创建Activity
public class ThreeActivity extends ActionBarActivity {
    RequestBody body = null;

    @Bind(R.id.btn_login)
    Button btn_login;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_three);
        ButterKnife.bind(this);

        Map<String, String> mapValuse = new HashMap<>();
        mapValuse.put("login_id", "150881");
        mapValuse.put("password", "123456");
        mapValuse.put("login_type", "mobile");
        mapValuse.put("device_id", UIUtil.getIMEI(UIUtil.getContext()));
        mapValuse.put("oauth_from", "");
        mapValuse.put("oauth_uid", "");
        mapValuse.put("access_token", "");

        body= RequestBodyUtil.getBody(mapValuse);

    }

    @OnClick(R.id.btn_login)
    void login(){
/*
        //第一种方法
        Call<LoginBean> call=loginApi.loginIn(body);
        call.enqueue(new Callback<LoginBean>() {
            @Override
            public void onResponse(Call<LoginBean> call, Response<LoginBean> response) {
                Log.e("huan",response.body().options.city);
            }

            @Override
            public void onFailure(Call<LoginBean> call, Throwable t) {
                Log.e("huan",t.toString());
            }
        });*/

        //第二种方法
        loginApi.loginIn(body).subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Observer<LoginBean>() {
                    @Override
                    public void onCompleted() {
//                        Intent intent = new Intent(ThreeActivity.this, FourActivity.class);
                        Intent intent = new Intent(ThreeActivity.this, FiveActivity.class);
                        startActivity(intent);
                        finish();
                    }

                    @Override
                    public void onError(Throwable e) {

                    }

                    @Override
                    public void onNext(LoginBean loginBean) {
                        BaseRequestUtil.saveToken(UIUtil.getContext(), loginBean.options.token);
                        BaseRequestUtil.saveMemberId(UIUtil.getContext(), loginBean.options.username);
                    }
                });
    }

}

第五步:辅助类
public class RequestBodyUtil {
    public static final MediaType mMEDIA_TYPE = MediaType.parse("application/json;charset=utf-8");

    public static RequestBody getBody(Map<String, String> valueMap){
        RequestBody body=null;
        String requestJson= UIUtil.convertRequest(valueMap);
        if(requestJson!=null){
            body = RequestBody.create(mMEDIA_TYPE, requestJson);
        }
        return body;
    }
}

//hashMap转为字符串
public static String convertRequest(Map<String, String> valueMap) {
    String jsonString;
    try {
        JSONObject json = new JSONObject();

        for (String key : valueMap.keySet()) {
            json.put(key, valueMap.get(key));
        }

        jsonString = json.toString().trim();
    } catch (JSONException e) {
        e.printStackTrace();
        jsonString = "";
    }
    return jsonString;
}

//获取会话token和IMEI码
public static Map<String, String> getHeaderMap() {
    Map<String, String> headerMap = new HashMap<>();
    String token = BaseRequestUtil.getToken(getContext());
    headerMap.put(BaseRequestUtil.REQUEST_TOKEN_PARAMS, token);
    String imei = UIUtil.getIMEI(getContext());
    headerMap.put(BaseRequestUtil.REQUEST_DEVICE_ID, imei);
    return headerMap;
}

/**
 * 获取imei
 */
public static String getIMEI(Context context) {
    TelephonyManager tm = (TelephonyManager) context.getSystemService(Context
            .TELEPHONY_SERVICE);
    return tm.getDeviceId();
}



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: RxJavaRetrofit是一种经常结合使用的技术,主要是因为它们都能够协同工作,优化Android应用的性能。 具体而言,RxJava是一种响应式编程框架,可以通过异步数据流的方式处理数据Retrofit则是一个RESTful框架,用于与服务器交互。因此,RxJava可以被用于处理从Retrofit返回的数据流。 这两个框架的结合使用可以让Android应用更快地处理数据并更好地应对网络请求。同时,通过使用RxJava的转换操作符,我们可以将从Retrofit返回的数据进行快速处理和转换。 ### 回答2: RXJava是一个响应式编程库,而Retrofit则是针对REST API进行网络请求和响应解析的框架。这两者结合使用,可以实现优雅的网络请求,并让代码更加简洁易懂。 Retrofit默认使用的是同步方法,这意味着如果在主线程中执行网络请求,就会阻塞主线程,造成卡顿甚至应用崩溃。为了避免这种情况,我们可以使用RXJava中的异步调度器,将网络请求放在IO线程中执行,并在请求完成后将结果回调到主线程中处理,保证应用的流畅性和响应性。 RXJava还提供了丰富的操作符,如map、filter、flatMap等,能够对网络请求的响应数据进行快速处理和转换,将数据转换成我们需要的格式,例如对象或列表。这样在显示数据时,可以节省大量的代码和时间。 另外,由于网络请求可能出现异常、网络超时等情况,我们需要对这些异常情况进行处理。RXJava提供了专门的异常处理操作符,如onErrorReturn、onErrorResumeNext等,能够快速捕获和处理网络请求异常,并在发生异常时执行相应的操作。 综上所述,RXJavaRetrofit结合使用,能够方便地实现优雅的网络请求和数据处理,以及有效地解决网络请求可能出现的异常情况,为开发者提供了更加便捷、高效、安全的开发体验。 ### 回答3: RxJavaRetrofit是目前Android开发中非常流行的两个库。他们都不是新兴的库,RxJava是由Netflix公司开发的响应式编程库,是在Java Future的基础上进行开发的。Retrofit是由Square公司开发的网络请求库。在进行Android开发时,我们一般会经常使用Retrofit来完成网络请求的操作,而配合使用RxJava可以让我们更加方便的处理网络请求的结果。 为什么要使用RxJavaRetrofitRetrofit是一个基于OkHttp的RESTful API请求框架,可以让我们通过定义相应的接口,来进行网络请求,使用简单而且很快,这也是为什么它会被Android开发者广泛使用的原因。而RxJava则是将异步事件组合在一起的响应式编程库,可以让我们以响应式的方式来处理网络请求的结果。因此,当我们结合使用这两个库时,就可以更加高效地完成Android的开发。 如何使用RxJavaRetrofit使用RxJavaRetrofit大致的流程如下: 1. 在build.gradle文件中添加RetrofitRxJava的依赖: ``` implementation 'com.squareup.retrofit2:retrofit:2.9.0' implementation 'com.squareup.retrofit2:converter-gson:2.9.0' implementation 'io.reactivex.rxjava2:rxjava:2.2.19' implementation 'io.reactivex.rxjava2:rxandroid:2.1.1' ``` 2. 定义Retrofit接口: ``` public interface ApiService { @GET("users") Observable<List<User>> getUsers(); } ``` 3. 使用RetrofitRxJava进行网络请求: ``` ApiService apiService = RetrofitClient.getInstance().create(ApiService.class); apiService.getUsers() .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .subscribe(new Observer<List<User>>() { @Override public void onSubscribe(Disposable d) { } @Override public void onNext(List<User> users) { // 成功获取到用户列表 } @Override public void onError(Throwable e) { // 网络请求失败 } @Override public void onComplete() { } }); ``` 在这个示例中,我们首先定义了一个ApiService接口,其中包含了我们需要进行网络请求的方法。在进行网络请求时,我们可以使用Retrofit的create()方法来实例化一个ApiService对象,然后使用subscribeOn()和observeOn()方法进行线程调度,最后使用subscribe()方法订阅Observer对象,即可完成网络请求的操作。 结论 RxJavaRetrofit可以很好地配合使用,使我们可以简洁、高效地处理网络请求的结果。配合使用可以大大提高我们的开发效率,同时也可以减少我们的代码量,让我们可以更加专注于业务逻辑的实现。因此,在进行Android开发时,建议使用这两个库来完成网络请求的操作。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值