Android 网络请求:OkHttp + Retrofit + RxJava 工具类详解

前言
在 Android 开发中,使用 OkHttp、Retrofit 和 RxJava 结合进行网络请求是一种常见的做法。这样的组合可以帮助我们更轻松地处理网络请求和响应,并在异步操作中使用 RxJava 的强大功能。本文将详细介绍如何创建一个网络请求工具类。

一、OkHttp + Retrofit + RxJava简介

OkHttp的优点:
1.支持Http/1.1 Http/2 网络协议
2.支持GZIP, 可以压缩下载体积
3.响应缓存可以直接避免重复请求
4.高效、灵活;通过连接池,减少了请求延迟
5.共享Socket,减少对服务器的请求次数

Retrofit的优点
可以配置不同HTTP client来实现网络请求,如okhttp、httpclient等
将接口的定义与使用分离开来,实现结构。
支持多种返回数据解析的Converter可以快速进行数据转换。
因为容易和RxJava结合使用,所以对于异步请求,同步请求也不需要做额外的工作。
Retrofit是基于OKHttp
优点1:简化逻辑,解耦了各个模块操作,单一化
比如要嵌套请求的时候,这个时候用flatMap操作符就可以实现优雅的链式嵌套请求
优点2:简化代码
它的操作符封装了规则,我们用一个操作符就可以实现许多功能
比如要打包网络请求,这个时候用zip就可以打包数据源
优点3:操作符强大,可以实现各种功能
flatmap解决嵌套回调的问题;mergeWith()可以把不同异步操作合并
优点4:最方便的是线程切换
优点5:错处处理
只要有异常发生onError()一定会被调用,这极大的简化了错误处理。只需要在一个地方处理错误即可以

Rxjava+Retrofit+Okhttp的优点
第一点:灵活。Retrofit是一个基于Restful的网络请求库,自身对OkHttp进行了封装,支持URL动态变化,所以我们完全可以在Retrofit的基础上再次对OkHttp进行简单的封装,比如封装一个OkHttpInterceptor等等。
第二点:链式编程。其实这个也是用Retrofit核心点了,可能很多人对链式编程并不感冒,但是这种编程风格一定会越来越火,因为链式编程让逻辑变得更加简洁(注意是逻辑而不是代码),增加了代码的可读性。同时Retrofit支持了RxJava这个优雅的异步请求库(后面我会出一篇文章专门讲这个库),与其组成了完美的技术CP,让我们的代码变得简洁、优雅。

二、添加依赖

首先,确保在你的 build.gradle 文件中添加 OkHttp、Retrofit、RxJava 和 Gson 的依赖:

implementation 'com.squareup.okhttp3:okhttp:4.9.0'
implementation 'io.reactivex.rxjava3:rxjava:3.0.13'
implementation 'io.reactivex.rxjava3:rxandroid:3.0.0'
implementation 'com.squareup.retrofit2:retrofit:2.9.0'
implementation 'com.squareup.retrofit2:converter-gson:2.9.0'

三、 创建网络请求接口

定义一个接口,其中包含 GET、POST 请求的定义。

import io.reactivex.rxjava3.core.Observable;
import okhttp3.RequestBody;
import retrofit2.http.Body;
import retrofit2.http.GET;
import retrofit2.http.POST;
import retrofit2.http.Query;

public interface ApiService {
    @GET("pathUrl")
    Observable<Object> deviceInfoAPI(@Query("deviceName") String deviceName);

    @POST("pathUrl")
    Observable<Object> userLoginAPI(@Body RequestBody requestBody);
}

pathUrl —> 表示请求的路径
deviceName —> 表示请求的路径参数
requestBody —> 表示请求的路径参数
Object —> 表示请求结果类型,可创建请求体实体类代替

四、创建 Retrofit 实例

创建 Retrofit 实例,并配置 OkHttp:

import java.util.concurrent.TimeUnit;
import okhttp3.ConnectionPool;
import okhttp3.OkHttpClient;
import retrofit2.Retrofit;
import retrofit2.adapter.rxjava3.RxJava3CallAdapterFactory;
import retrofit2.converter.gson.GsonConverterFactory;

public class RetrofitClient {

    private static final String BASE_URL = "https://test-***/";
    private static Retrofit retrofit;
    private static OkHttpClient mOkHttpClient;
    
    private static final int TIMEOUT_CONNECT = 10;// 连接超时时间(秒)
    private static final int TIMEOUT_READ = 30;// 读取超时时间(秒)
    private static final int TIMEOUT_WRITE = 30; // 写入超时时间(秒)
    private static final int MAX_IDLE_CONNECTIONS = 8; // 最大空闲连接数
    private static final int KEEP_ALIVE_DURATION = 30;// 空闲连接保持时间(秒)
    private static final TimeUnit KEEP_ALIVE_TIME_UNIT = TimeUnit.SECONDS; // 空闲连接保持时间单位
    private static HashMap<String, String> headMap = new HashMap<>();//头部信息
    private RetrofitClient() {
        // Private constructor to prevent instantiation.
    }

    /**
     * 获取 OkHttpClient 实例
     * @return OkHttpClient 实例
     */
    public static OkHttpClient getOkHttpClient() {
        if (mOkHttpClient == null) {
        //使用连接池,尽量保持TCP连接的复用,而不是立即关闭。 
            ConnectionPool connectionPool = new ConnectionPool(MAX_IDLE_CONNECTIONS, KEEP_ALIVE_DURATION, KEEP_ALIVE_TIME_UNIT);
            mOkHttpClient = new OkHttpClient.Builder()
                    .connectTimeout(TIMEOUT_CONNECT, TimeUnit.SECONDS)
                    .readTimeout(TIMEOUT_READ, TimeUnit.SECONDS)
                    .writeTimeout(TIMEOUT_WRITE, TimeUnit.SECONDS)
                    .connectionPool(connectionPool)
                    .addInterceptor(new BaseInterceptor(headerMap))//添加头部信息
                    .build();
        }
        return mOkHttpClient;
    }
    
    public static Retrofit getInstance() {
        if (retrofit == null) {
            retrofit = new Retrofit.Builder()
                    .baseUrl(BASE_URL)
                    .client(getOkHttpClient())
                    .addConverterFactory(GsonConverterFactory.create())
                    .addCallAdapterFactory(RxJava3CallAdapterFactory.create())
                    .build();
        }
        return retrofit;
    }
}
import java.io.IOException;
import java.util.Map;
import java.util.Set;

import okhttp3.Interceptor;
import okhttp3.Request;
import okhttp3.Response;

/**
 * @Author: Su
 * @Date: 2023/11/18
 * @Description:
 */
public class BaseInterceptor implements Interceptor {
    private Map<String, String> headers;

    public BaseInterceptor(Map<String, String> headers) {
        this.headers = headers;
    }

    @Override
    public Response intercept(Chain chain) throws IOException {

        Request.Builder builder = chain.request()
                .newBuilder();
        builder.addHeader("Content-Type", "application/json;charset=UTF-8").build();
        if (headers != null && headers.size() > 0) {
            Set<String> keys = headers.keySet();
            for (String headerKey : keys) {
                builder.addHeader(headerKey, headers.get(headerKey)).build();
            }
        }
        return chain.proceed(builder.build());

    }
}

五、创建网络请求工具类

创建一个网络请求工具类 NetworkUtils,封装具体的网络请求逻辑:

public class NetworkUtils {

    private static final ApiService apiService = RetrofitClient.getInstance().create(ApiService.class);

    private NetworkUtils() {
        // Private constructor to prevent instantiation.
    }

    public static Observable<Object> getDeviceInfo(String deviceName) {
        return apiService.deviceInfoAPI(deviceName)
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread());
    }

    public static Observable<Object> userLoginResult(RequestBody requestBody) {
        return apiService.userLoginAPI(requestBody)
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread());
    }
}

deviceName —> 表示请求的路径参数
requestBody —> 表示请求的路径参数
Object —> 表示请求结果类型,可创建请求体实体类代替

六、使用网络请求工具类

import android.util.Log;
import org.json.JSONObject;
import io.reactivex.rxjava3.annotations.NonNull;
import io.reactivex.rxjava3.observers.DisposableObserver;
import okhttp3.MediaType;
import okhttp3.RequestBody;

public class MainActivity extends AppCompatActivity {

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

        NetworkUtils.getDeviceInfo("deviceName").safeSubscribe(new DisposableObserver<DeviceInfoBean>() {
            @Override
            public void onNext(@NonNull Object s) {
                Log.e("onNext--->",String.valueOf(s));
            }

            @Override
            public void onError(@NonNull Throwable e) {
                Log.e("onError--->",String.valueOf(e.getMessage()));
            }

            @Override
            public void onComplete() {
                Log.e("onComplete--->","Complete");
            }
        });
        
        JSONObject params = new JSONObject();
        try {
            params.put("userName","***");
            params.put("password","***");
        }catch (Exception e){
            e.printStackTrace();
        }
        RequestBody requestBody = RequestBody.create(MediaType.parse("application/json;charset=utf-8"),String.valueOf(params));
        NetworkUtils.userLoginResult(requestBody).safeSubscribe(new DisposableObserver<LoginBean>() {
            @Override
            public void onNext(@NonNull Object loginBean) {
                Log.e("onNext--->",String.valueOf(loginBean));
            }

            @Override
            public void onError(@NonNull Throwable e) {
                Log.e("onError--->",String.valueOf(e.getMessage()));
            }

            @Override
            public void onComplete() {
                Log.e("onComplete--->","Complete");
            }
        });
    }
}

总结
OkHttp + Retrofit + RxJava 工具类的结合可以方便地完成 Android 网络请求的任务,以下是该工具类的总结:

1.定义 Retrofit 接口 在 Retrofit 接口中定义网络请求的方法,包括请求方法(GET/POST/PUT/DELETE等)、请求路径、请求参数、请求头部、返回类型等信息。
2.使用 Retrofit 创建服务 使用 Retrofit.Builder 创建 Retrofit 实例,并使用 create() 方法创建服务实例,使用该实例即可进行请求。
3.添加 OkHttp 拦截器 可以添加 OkHttp 拦截器来实现对请求进行拦截和修改,比如对请求头部添加认证信息、对请求参数进行加密等。
4.使用 RxJava 进行线程切换 使用 RxJava 进行线程切换可以避免在主线程中进行耗时操作而导致主线程卡顿,同时也方便地进行异步任务的处理。
5.封装网络请求工具类 可以将 Retrofit、OkHttp、RxJava 等技术封装到一个网络请求工具类中,方便地进行调用和维护。

综上所述,OkHttp + Retrofit + RxJava 工具类的结合可以方便地完成 Android 网络请求的任务,同时也可以提高请求的效率和可维护性。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Android程序Su

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值