Retrofit+OkHttp+RxJava+RxAndroid详解(上)

上节讲述了Retrofit的基本使用,本章节讲述Retrofit结合OkHttp,RxJava,RxAndroid使用讲解。

Retrofit基础讲解(上)

Retrofit基础讲解(上)_jianning-wu的博客-CSDN博客

Retrofit基础讲解(下)

Retrofit基础讲解(下)_数组 链表 字典的区别_jianning-wu的博客-CSDN博客

RxJava系列

https://blog.csdn.net/weixin_37730482/category_10501619.html

一.简介

单单引入Retrofit其实已经包含了一部分OkHttp的Jar包。也可以完全完成网络的请求。那么为什么要结合OkHttp使用呢?因为OkHttp可以设置很多。比如拦截器,比如实现Https,比如Cookie的管理等等。

而引入RxJava和RxAndroid是为了更好地完成线程切换。

二.具体实现

1.注意:

依赖Retrofit的组合API时,需要依赖很多包。比如Retrofit的RxJava的依赖。此时项目中如果已经依赖了RxJava。可能就会有依赖冲突问题。

问题描述

More than one file was found with OS independent path 'META-INF/rxjava.properties'.

问题原因

因为项目本身有一个RxJava的单独依赖,Retrofit的RxJava也是一个RxJava依赖,所以会冲突

Retrofit的RxJava依赖生成Jar包

也就是说Retrofit的RxJava不仅下载了Retrofit的adapter的RxJava,也会下载一个单独的RxJava包。

然后项目中本身也有一个RxJava的依赖。

implementation 'io.reactivex:rxjava:1.3.2'

下载的Jar包

所以会有冲突。

问题解决

<1> Gradle配置忽略冲突

defaultConfig {
        applicationId "com.wjn.networkdemo"
        minSdkVersion 19
        targetSdkVersion 26
        versionCode 1
        versionName "1.0"

        packagingOptions {
            //解决编译时com.android.builder.merge.DuplicateRelativeFileException: More than one file was found with OS independent path 'META-INF/rxjava.properties'这个错误
            exclude 'META-INF/rxjava.properties'
        }

        testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
    }

<2> Retrofit的RxJava依赖修改

修改前

implementation 'com.squareup.retrofit2:adapter-rxjava2:2.3.0'

修改后

//Retrofit支持RxJava方式回调
implementation ('com.squareup.retrofit2:adapter-rxjava2:2.3.0'){
    exclude group: "io.reactivex.rxjava2", module: "rxjava"
}

修改后

以上Jar消失,编译成功。

<dependency>
    <groupId>io.reactivex.rxjava2</groupId>
    <artifactId>rxjava</artifactId>
</dependency>

group取值:上述groupId值

module取值:上述artifactId值

2.Gradle依赖

//OkHttp
implementation 'com.squareup.okhttp3:okhttp:3.9.0'

//RxJava
implementation 'io.reactivex.rxjava2:rxjava:2.0.1'

//RxAndroid
implementation 'io.reactivex.rxjava2:rxandroid:2.0.1'

//Retrofit
implementation 'com.squareup.retrofit2:retrofit:2.7.0'
    
//Retrofit支持RxJava方式回调 忽略此包的下载 避免RxJavaJar包重复
implementation ('com.squareup.retrofit2:adapter-rxjava2:2.3.0'){
    exclude group: "io.reactivex.rxjava2", module: "rxjava"
}

3.接口

package com.wjn.networkdemo.retrofit.rx;

import io.reactivex.Observable;
import okhttp3.ResponseBody;
import retrofit2.http.GET;

public interface FanYiRxService {

    /**
     * 翻译模块Get请求
     *
     * @return Observable
     */

    @GET("openapi.do?keyfrom=imoocdict123456&key=324273592&type=data&doctype=json&version=1.1&q=blue")
    Observable<ResponseBody> getFanYiByGet();

}

使用RxJava后,返回值变成Observable(被观察者) 注意依赖的RxJava必须要和Retrofit的RxJava版本一致(比如都是2.XXX),否则报错。

单独的RxJava

implementation 'io.reactivex.rxjava2:rxjava:2.0.1'

Retrofit的RxJava

implementation ('com.squareup.retrofit2:adapter-rxjava2:2.3.0'){
   exclude group: "io.reactivex.rxjava2", module: "rxjava"
}

4.测试类

package com.wjn.networkdemo.retrofit.rx;

import android.os.Bundle;
import android.util.Log;
import android.view.View;

import androidx.appcompat.app.AppCompatActivity;

import com.wjn.networkdemo.R;

import java.io.IOException;
import java.util.concurrent.TimeUnit;

import io.reactivex.Observer;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.disposables.Disposable;
import io.reactivex.schedulers.Schedulers;
import okhttp3.OkHttpClient;
import okhttp3.ResponseBody;
import retrofit2.Retrofit;
import retrofit2.adapter.rxjava2.RxJava2CallAdapterFactory;

public class RetrofitRxActivity extends AppCompatActivity {

    private Retrofit mRetrofit;
    private FanYiRxService mFanYiRxService;
    private String mBaseUrl = "http://fanyi.youdao.com/";

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

        //配置okHttp的参数
        OkHttpClient okHttpClient = new OkHttpClient.Builder()
                .connectTimeout(3000, TimeUnit.SECONDS)
                .build();

        //获取Retrofit对象
        mRetrofit = new Retrofit.Builder()
                .baseUrl(mBaseUrl)//设置BaseUrl 必须以'/'结尾
                .client(okHttpClient)//设置使用OkHttp请求
                .addCallAdapterFactory(RxJava2CallAdapterFactory.create())//配置回调库,采用RxJava
                .build();

        //IO线程请求数据 UI线程更新数据
        findViewById(R.id.activity_retrofit_rx_textview1).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                getData();
            }
        });

        //IO线程请求数据 子线程更新数据
        findViewById(R.id.activity_retrofit_rx_textview2).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                getDataNew();
            }
        });
    }

    /**
     * Retrofit Get请求
     * 被观察者 IO线程 请求接口
     * 观察者 UI线程 更新UI
     */

    private void getData() {
        if (null != mRetrofit) {
            mFanYiRxService = mRetrofit.create(FanYiRxService.class);
            mFanYiRxService.getFanYiByGet()
                    .subscribeOn(Schedulers.io())
                    .observeOn(AndroidSchedulers.mainThread())
                    .subscribe(new Observer<ResponseBody>() {

                        @Override
                        public void onComplete() {
                            Log.d("RetrofitRxActivity", "onComplete方法");
                            Log.d("RetrofitRxActivity", "onComplete方法 线程----:" + Thread.currentThread().getName());
                        }

                        @Override
                        public void onSubscribe(Disposable d) {

                        }

                        @Override
                        public void onNext(ResponseBody value) {
                            if (null == value) return;

                            String result = null;
                            try {
                                result = value.string();
                            } catch (IOException e) {
                                e.printStackTrace();
                            }
                            Log.d("RetrofitRxActivity", "onNext方法 result----:" + result);
                            Log.d("RetrofitRxActivity", "onNext方法 线程----:" + Thread.currentThread().getName());
                        }

                        @Override
                        public void onError(Throwable e) {
                            Log.d("RetrofitRxActivity", "onError方法e.toString()----:" + e.toString());
                            Log.d("RetrofitRxActivity", "onError方法 线程----:" + Thread.currentThread().getName());
                        }

                    });
        }
    }

    /**
     * Retrofit Get请求
     * 被观察者 IO线程 请求接口
     * 观察者 子线程 更新UI
     */

    private void getDataNew() {
        if (null != mRetrofit) {
            mFanYiRxService = mRetrofit.create(FanYiRxService.class);
            mFanYiRxService.getFanYiByGet()
                    .subscribeOn(Schedulers.io())
                    .observeOn(Schedulers.newThread())
                    .subscribe(new Observer<ResponseBody>() {

                        @Override
                        public void onComplete() {
                            Log.d("RetrofitRxActivity", "onComplete方法");
                            Log.d("RetrofitRxActivity", "onComplete方法 线程----:" + Thread.currentThread().getName());
                        }

                        @Override
                        public void onSubscribe(Disposable d) {

                        }

                        @Override
                        public void onNext(ResponseBody value) {
                            if (null == value) return;

                            String result = null;
                            try {
                                result = value.string();
                            } catch (IOException e) {
                                e.printStackTrace();
                            }
                            Log.d("RetrofitRxActivity", "onNext方法 result----:" + result);
                            Log.d("RetrofitRxActivity", "onNext方法 线程----:" + Thread.currentThread().getName());
                        }

                        @Override
                        public void onError(Throwable e) {
                            Log.d("RetrofitRxActivity", "onError方法e.toString()----:" + e.toString());
                            Log.d("RetrofitRxActivity", "onError方法 线程----:" + Thread.currentThread().getName());
                        }

                    });
        }
    }
}

5.结果

<1> IO线程请求 UI线程更新

D/RetrofitRxActivity: onNext方法 result----:{"translation":["蓝色的"],"basic":{"us-phonetic":"bluː","phonetic":"bluː","uk-phonetic":"bluː","explains":["adj. 蓝色的;忧郁的,悲观的;(由于冷或呼吸困难)发青的,青紫的;(电影、玩笑或故事)色情的,黄色的;(肉)未熟的;(政治上)保守的","n. 蓝色;蓝色物品;(牛津或剑桥大学的运动员)蓝色荣誉者;失误;红发人;打架","vt. (使)变成蓝色;把......染成蓝色;给\u2026\u2026上蓝色漂白剂;挥霍(钱财)","n. (Blue) (英、美、加、澳、新)布卢(人名)"]},"query":"blue","errorCode":0,"web":[{"value":["蓝色的","蓝色","刀枪不入"],"key":"blue"},{"value":["钴蓝色","艳蓝色","钴蓝","群青"],"key":"Cobalt blue"},{"value":["蓝月","蓝月亮","千载难逢的时机","蓝色月亮"],"key":"Blue Moon"}]}


 D/RetrofitRxActivity: onNext方法 线程----:main


D/RetrofitRxActivity: onComplete方法


D/RetrofitRxActivity: onComplete方法 线程----:main

<2> IO线程请求 子线程更新

D/RetrofitRxActivity: onNext方法 result----:{"translation":["蓝色的"],"basic":{"us-phonetic":"bluː","phonetic":"bluː","uk-phonetic":"bluː","explains":["adj. 蓝色的;忧郁的,悲观的;(由于冷或呼吸困难)发青的,青紫的;(电影、玩笑或故事)色情的,黄色的;(肉)未熟的;(政治上)保守的","n. 蓝色;蓝色物品;(牛津或剑桥大学的运动员)蓝色荣誉者;失误;红发人;打架","vt. (使)变成蓝色;把......染成蓝色;给\u2026\u2026上蓝色漂白剂;挥霍(钱财)","n. (Blue) (英、美、加、澳、新)布卢(人名)"]},"query":"blue","errorCode":0,"web":[{"value":["蓝色的","蓝色","刀枪不入"],"key":"blue"},{"value":["钴蓝色","艳蓝色","钴蓝","群青"],"key":"Cobalt blue"},{"value":["蓝月","蓝月亮","千载难逢的时机","蓝色月亮"],"key":"Blue Moon"}]}


D/RetrofitRxActivity: onNext方法 线程----:RxNewThreadScheduler-1


D/RetrofitRxActivity: onComplete方法


D/RetrofitRxActivity: onComplete方法 线程----:RxNewThreadScheduler-1

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值