网络请求--RXJava+okhttp 进行网络下载操作

下载文件(实时返回下载进度)

RxJava中的事件源(被观察者):这里配合OkHttp进行进行网络操作,

File path = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES);
File file = new File(path,"/okhttpdownload");
/**
 * download file with OkHttp and RxJava (rate) 
 */
Observable downloadObservable = Observable.create(new Observable.OnSubscribe() {
    @Override
    public void call(Subscriber subscriber) {
        InputStream inputStream = null;
        OutputStream outputStream = null;
        OkHttpClient client = new OkHttpClient();
        Request request = new Request.Builder()
                      .url("Https://xxxx.txt")
                      .build();
        try{
            Response response = client.newCall(request).execute();
            if (response.isSuccessful()){
                  inputStream = response.body().byteStream();
                  long length = response.body().contentLength();
                  //将文件下载到file路径下
                  outputStream = new FileOutputStream(file);
                  byte data[] = new byte[1024];
                  subscriber.onNext("0%");
                  long total = 0;
                  int count;
                  while ((count = inputStream.read(data)) != -1){
                        total += count;
                        // 返回当前实时进度
                        subscriber.onNext(String.valueOf(total*100/length) + "%");
                        outputStream.write(data,0,count);
                    }
                outputStream.flush();
                outputStream.close();
                inputStream.close();
            }
        }catch (IOException e){
            //告诉订阅者错误信息
            subscriber.onError(e);
        }finally {
            if (inputStream != null){
                try{
                    inputStream.close();
                }catch (IOException e){}
            }
            if (outputStream != null){
                try {
                    outputStream.close();
                }catch (IOException e){}
            }
        }
        //告诉订阅者请求数据结束
        subscriber.onCompleted();
  });

事件源写好后,就要开始使用RxJava订阅事件了;

downloadobservable.subscribeOn(Schedulers.io())
    .onBackpressureBuffer()
    .observeOn(AndroidSchedulers.mainThread())
    .subscribe(new Subscriber() {
        @Override
        public void onCompleted() {
            //接收到事件源的onCompleted后的操作
            //一般是取消downloading dialog的操作
        }
        @Override
        public void onError(Throwable e) {
            //接收事件源的错误信息操作
            log.e(e.toString());
        }
        @Override
        public void onNext(String s) {
            // 接受实时的下载进度
            log.d(s);
        }
    });

我认为RxJava中,设计最精妙的就是 .subscribeOn() 和 .observeOn()两个操作了,它可以轻而易举的实现Android中主线程和IO线程的切换,从而让我们可以完全抛弃Handler和AsyncTask。

下载Bitmap图片

虽然Square专门出了一款图片处理的开源库Picasso(下一篇会介绍到),但是如果想要用OkHttp配合RxJava下载图片并现实该怎么做呢?

还是通过RxJava的框架来实现:

Observable downloadDrawble = Observable.create(new Observable.OnSubscribe() {
    @Override
    public void call(Subscriber subscriber) {
        OkHttpClient client = new OkHttpClient();
        Request request = new Request.Builder()
                .url(url)
                .build();
        try {
            Response response = client.newCall(request).execute();
            if (response.isSuccessful()){
                InputStream input = response.body().byteStream();
                Bitmap bitmap = BitmapFactory.decodeStream(input);
                subscriber.onNext(bitmap);
            }
        }catch (IOException e){
            subscriber.onError(e);
        }
        subscriber.onCompleted();
    }
});

其实下载图片这里和上面的文件下载大致无二,只是将inputstream转换成bitmap的格式。这里没有将文件下载到本地,而是下载到内存中,应用关闭后会清除数据。事件的订阅和上文一样,可以在onNext()中更新UI,这里会回调到主线程

你可能感兴趣的:(网络开发)