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

本文介绍了如何结合RxJava和OkHttp进行网络下载操作,特别是下载Bitmap图片。通过RxJava的.subscribeOn()和.observeOn()轻松实现线程切换,避免使用Handler和AsyncTask。在下载图片时,将InputStream转换为Bitmap格式,并在onNext()方法中更新UI,确保在主线程执行。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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

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

File path = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES);
File file = new File(path,"/okhttpdownload");
/**
 * download file with OkHttp and RxJava (rate) 
 */
Observable<String> downloadObservable = Observable.create(new Observable.OnSubscribe<String>() {
    @Override
    public void call(Subscriber<? super String> 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<String>() {
        @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<Bitmap> downloadDrawble = Observable.create(new Observable.OnSubscribe<Bitmap>() {
    @Override
    public void call(Subscriber<? super Bitmap> 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,这里会回调到主线程

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值