RxAndroid+OKHttp进行网络请求

Rx(Reactive Extensions)响应式编程,本质是观察者模式,是以观察者和订阅者为基础的异步响应方式,它是一种编程思想的突破。

 

Rxandroid有四个基本的概念:Observable(被观察者)、Observer(观察者)、subscribe(订阅)、事件。

Observer Observable Subscribe 关键是这三个类以及其中方法的使用。

如何创建观察者、被观察者、如何订阅事件?

 

基本原理:

1)Observable对象通过调用subscribe(new Subscriber{ })方法与观察者实现订阅关系.subscribe()方法将观察者和被观察者联结起来.

2)编写的工具类,只是为了获取Observable被观察者对象.

3)在被观察者中,通过OKHttp进行常规的网络访问操作.

4)观察者的回调方法 onNext()onComplete()onError()

onNext(T) 被观察者调用这个方法发送数据,方法的参数就是 Observable 发送的数据,这个方法可以被调用多次 .
onComplete() 当被观察者遇到错误,或者无法返回期望的数据时就会调用这个方法,这个调用会终止被观察者,后续不会再调用 onNext() onComplete().onError() 方法的参数,就是抛出的异常 .

onComplete() 正常终止,如果没有遇到错误,被观察者在最后一次调用onNext()方法之后调用此方法.

5)在创建被观察者的create()方法里面,检查观察者的订阅状态isUnsubscribed,以便在没有观察者的时候,让被观察者停止发送数据.

6)被观察者决定什么时候触发事件以及触发怎样的事件,Rxjava使用Create()方法来创建一个被观察者,并为他定义事件触发规则. 当网络请求拿到结果的时候,触发事件,发送数据给观察者 subscriber.onNext(response.body().string());

观察者模式面向的需求是:A对象(观察者)对B对象(被观察者)的某种变化高度敏感需要在B变化的一瞬间做出反应

RxAndroid最核心的两个东西是Observables(被观察者,事件源)和Subscribers(订阅者)。Observables发出一系列事件,Subscribers处理这些事件。这里的事件可以是任何你感兴趣的东西,触摸事件,web接口调用返回的数据等等。

普通的异步编程方式存在的问题:

访问网络接口调用返回数据,尤其是在使用接口回调时,处理数据很麻烦。


案例一:下载图片

Activity中的代码:

package com.crs.demo.ui.rx;

import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;

import com.crs.demo.R;
import com.crs.demo.base.BaseActivity;
import com.crs.demo.constant.UrlConstant;
import com.crs.demo.utils.LogUtils;

import rx.Subscriber;
import rx.android.schedulers.AndroidSchedulers;
import rx.schedulers.Schedulers;

/**
 * Created on 2016/9/19.
 * Author:crs
 * Description:使用RxAndroid+OKHttp进行图片的下载
 */
public class RxDownLoadImgActivity extends BaseActivity implements View.OnClickListener {

    private static String TAG = RxDownLoadImgActivity.class.getSimpleName();
    private Button btn_rx_download_img;
    private ImageView iv_rx_download_img;
    private DownloadUtils mDownloadUtils;

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

        initViews();
        initListener();

        //持有网络请求类的引用
        mDownloadUtils = new DownloadUtils();
    }


    private void initViews() {
        btn_rx_download_img = findView(R.id.btn_rx_download_img);
        iv_rx_download_img = findView(R.id.iv_rx_download_img);
    }

    private void initListener() {
        btn_rx_download_img.setOnClickListener(this);
    }

    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.btn_rx_download_img: {
                //观察者和被观察者通过subscribe()方法实现绑定
                mDownloadUtils.downloadImage(UrlConstant.IMAGE_URL)
                        .subscribeOn(Schedulers.io())//IO操作
                        .observeOn(AndroidSchedulers.mainThread())//切换到主线程里面
                        .subscribe(new Subscriber<byte[]>() {
                            @Override
                            public void onCompleted() {
                                //主要用于处理加载对话框的显示与隐藏
                            }

                            @Override
                            public void onError(Throwable e) {
                                LogUtils.e(TAG, e.getMessage());

                            }

                            @Override
                            public void onNext(byte[] bytes) {
                                //从服务器端获取的字节数组对象,通过BitmapFactory把字节数组转化成Bitmap对象
                                Bitmap bitmap = BitmapFactory.decodeByteArray(bytes, 0, bytes.length);
                                iv_rx_download_img.setImageBitmap(bitmap);
                            }
                        });
            }
            break;
        }
    }

}

DownloadUtils中的代码:

package com.crs.demo.ui.rx;

import com.squareup.okhttp.Callback;
import com.squareup.okhttp.OkHttpClient;
import com.squareup.okhttp.Request;
import com.squareup.okhttp.Response;

import java.io.IOException;

import rx.Observable;
import rx.Subscriber;

/**
 * Created on 2016/9/19.
 * Author:crs
 * Description:下载工具类
 */
public class DownloadUtils {

    private OkHttpClient httpUtils;

    public DownloadUtils() {
        httpUtils = new OkHttpClient();
    }

    /**
     * 定义下载方法,使用rx的编程思想
     *
     * @param url
     * @return
     */
    public Observable<byte[]> downloadImage(final String url) {
        //创建被观察者
        return Observable.create(new Observable.OnSubscribe<byte[]>() {
            @Override
            public void call(final Subscriber<? super byte[]> subscriber) {
                //判断观察者和被观察者是否存在订阅关系
                if (!subscriber.isUnsubscribed()) {
                    Request request = new Request.Builder().url(url).build();
                    httpUtils.newCall(request).enqueue(new Callback() {
                        @Override
                        public void onFailure(Request request, IOException e) {
                            subscriber.onError(e);
                        }

                        @Override
                        public void onResponse(Response response) throws IOException {
                            if (response.isSuccessful()) {
                                //拿到结果的一瞬间触发事件,并传递数据给观察者
                                //把请求结果转化成字节数组
                                byte[] bytes = response.body().bytes();
                                subscriber.onNext(bytes);
                            }
                            //数据发送已经完成
                            subscriber.onCompleted();
                        }
                    });


                }
            }
        });

    }


}

案例二:查询订单数据操作

Activity中的代码:

package com.crs.demo.ui.rx;

import android.os.Bundle;
import android.text.TextUtils;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;

import com.crs.demo.R;
import com.crs.demo.base.BaseActivity;
import com.crs.demo.constant.UrlConstant;
import com.crs.demo.utils.ToastUtils;

import org.json.JSONException;
import org.json.JSONObject;

import rx.Subscriber;
import rx.android.schedulers.AndroidSchedulers;
import rx.schedulers.Schedulers;

/**
 * Created on 2016/9/19.
 * Author:crs
 * Description:使用RxAndroid+OKHttp进行查询数据的操作
 */
public class RxPostDataActivity extends BaseActivity implements View.OnClickListener {

    private Button btn_rx_post_data;
    private EditText et_rx_post_data;
    private QueryUtils mQueryUtils;

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

        initViews();
        initListener();

        //持有业务逻辑类的引用
        mQueryUtils = new QueryUtils();


    }


    private void initViews() {
        btn_rx_post_data = findView(R.id.btn_rx_post_data);
        et_rx_post_data = findView(R.id.et_rx_post_data);

    }

    private void initListener() {
        btn_rx_post_data.setOnClickListener(this);
    }

    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.btn_rx_post_data: {
                String orderId = et_rx_post_data.getText().toString().trim();
                if (TextUtils.isEmpty(orderId)) {
                    return;
                }

                mQueryUtils.queryOrder(UrlConstant.ORDER_STATUS_POST, orderId)
                        .subscribeOn(Schedulers.io())
                        .observeOn(AndroidSchedulers.mainThread())
                        .subscribe(new Subscriber<String>() {
                            @Override
                            public void onCompleted() {

                            }

                            @Override
                            public void onError(Throwable e) {

                            }

                            @Override
                            public void onNext(String s) {
                                //服务器端返回的为json字符串
                                try {
                                    JSONObject jsonObject = new JSONObject(s);
                                    int code = jsonObject.getInt("Code");
                                    if (code == 1) {
                                        ToastUtils.showShort(RxPostDataActivity.this, "查询成功");
                                    }
                                } catch (JSONException e) {
                                    e.printStackTrace();
                                }
                            }
                        });


            }
            break;
        }

    }
}


QueryUtils中的代码:

package com.crs.demo.ui.rx;

import com.squareup.okhttp.Callback;
import com.squareup.okhttp.FormEncodingBuilder;
import com.squareup.okhttp.OkHttpClient;
import com.squareup.okhttp.Request;
import com.squareup.okhttp.RequestBody;
import com.squareup.okhttp.Response;

import java.io.IOException;

import rx.Observable;
import rx.Subscriber;

/**
 * Created on 2016/9/19.
 * Author:crs
 * Description:查询工具类
 */
public class QueryUtils {

    private OkHttpClient httpUtils;

    public QueryUtils() {
        httpUtils = new OkHttpClient();
    }

    /**
     * 定义查询操作,使用rx的编程思想
     *
     * @param url
     * @param orderId
     * @return
     */
    public Observable<String> queryOrder(final String url, final String orderId) {
        return Observable.create(new Observable.OnSubscribe<String>() {
            @Override
            public void call(final Subscriber<? super String> subscriber) {
                if (!subscriber.isUnsubscribed()) {
                    RequestBody body = new FormEncodingBuilder().add("orderNo", orderId).build();
                    Request request = new Request.Builder().url(url).post(body).build();
                    httpUtils.newCall(request).enqueue(new Callback() {
                        @Override
                        public void onFailure(Request request, IOException e) {
                            subscriber.onError(e);
                        }

                        @Override
                        public void onResponse(Response response) throws IOException {
                            if (response.isSuccessful()) {
                                String str = response.body().string();
                                subscriber.onNext(str);
                            }
                            subscriber.onCompleted();
                        }
                    });
                }
            }
        });
    }

}

响应式编程中存在大量的操作符.

From操作:

将其他种类的对象和数据类型转化成Observable;当你使用Observable时要处理的数据类型都可以转化成Observables

 

使用RX模式的优点:

一、使用观察者模式

创建:Rx可以方便的创建事件流和数据流;

组合:Rx使用查询式的操作符组合和变换数据流;

监听:Rx可以订阅任何可观察的数据流并执行操作;

 

二、简化代码

函数式风格: 对可观察数据流使用无副作用的输入输出函数,避免了程序里错综复杂的状态。

简化代码: Rx操作符通常可以将复杂的问题简化为很少的几行代码。

异步错误处理:传统的try/catch没办法处理异步计算,Rx提供了合适的错误处理机制。

轻松使用并发:RxObservablesSchedulers让开发者可以摆脱底层的线程同步和各种并发问题。

 

三、操作符

Rx提供了一系列操作符,用他们来过滤filter、选择select、变换transform、结合combine和组合compose多个Observable,这些操作符让执行和符合变得非常高效。

可以把Observable当做iterable(迭代器)的推送方式的等价物,使用iterable,消费者从生产者那拉取数据,线程阻塞直至数据准备好。使用Observable,在数据准备好时,生产者将数据推送给消费者,数据同步或者一部到达,这种方式更灵活。

 

添加支持jdk1.8的代码  使用lamb

添加了一些依赖 和配置文件

使用纯java代码来实现观察者模式  定义一个接口Watcher  定义一些更改的状态

定义一个接口规范被观察者的行为

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值