Android Retrofit + RxJava + OkHttp 網絡請求高效封裝方案

Retrofit + RxJava + OkHttp 是 Android 開發中常用的網絡請求庫組合。Retrofit 是一個類型安全的 HTTP 客戶端,RxJava 是一個響應式編程庫,OkHttp 是一個高效的 HTTP 客戶端。

Retrofit + RxJava + OkHttp 的組合可以提供以下功能:
職責清晰

RetrofitClient 負責 Retrofit 和 OkHttp 的初始化。
ApiServiceHelper 負責動態創建 API 服務實例。
NetworkHelper 負責發起網絡請求和處理結果

1. 動態配置 Retrofit 和 OkHttp
允許在運行時動態修改 Retrofit 和 OkHttp 的配置,例如 Base URL、超時時間、攔截器等。

  1. 統一錯誤處理
    增強錯誤處理的靈活性,支持自定義錯誤處理器。

  2. 支持多環境切換
    通過配置文件或 Build Variants 動態切換測試環境和生產環境。

  3. 添加緩存機制
    通過 OkHttp 的緩存攔截器實現本地緩存,減少網絡請求。

  4. Token 自動管理
    通過攔截器自動添加 Token 并處理 Token 過期。

  5. 支持文件上傳/下載
    擴展 API 服務接口,支持文件操作。

  6. 日志優化
    根據不同的 Build 類型(Debug/Release)動態調整日志級別。

  7. 生命周期綁定
    將網絡請求與 Activity/Fragment 的生命周期綁定,避免內存泄漏。

代碼如下:
RetrofitClient:支持動態配置

import okhttp3.Cache;
import okhttp3.OkHttpClient;
import okhttp3.logging.HttpLoggingInterceptor;
import retrofit2.Retrofit;
import retrofit2.adapter.rxjava3.RxJava3CallAdapterFactory;
import retrofit2.converter.gson.GsonConverterFactory;
import java.io.File;
import java.util.concurrent.TimeUnit;public class RetrofitClient {private static Retrofit retrofit;private static OkHttpClient okHttpClient;private RetrofitClient() {// 私有構造函數,防止外部實例化}public static Retrofit getRetrofit() {if (retrofit == null) {synchronized (RetrofitClient.class) {if (retrofit == null) {retrofit = new Retrofit.Builder().baseUrl("https://api.example.com/") // 默認 Base URL.client(getOkHttpClient()).addConverterFactory(GsonConverterFactory.create()).addCallAdapterFactory(RxJava3CallAdapterFactory.create()).build();}}}return retrofit;}public static OkHttpClient getOkHttpClient() {if (okHttpClient == null) {synchronized (RetrofitClient.class) {if (okHttpClient == null) {OkHttpClient.Builder builder = new OkHttpClient.Builder().connectTimeout(10, TimeUnit.SECONDS).readTimeout(10, TimeUnit.SECONDS).writeTimeout(10, TimeUnit.SECONDS);// 添加緩存(10MB)File cacheDir = new File(System.getProperty("java.io.tmpdir"), "http-cache");builder.cache(new Cache(cacheDir, 10 * 1024 * 1024));// 添加日志攔截器(僅在 Debug 模式下啟用)if (BuildConfig.DEBUG) {HttpLoggingInterceptor logging = new HttpLoggingInterceptor();logging.setLevel(HttpLoggingInterceptor.Level.BODY);builder.addInterceptor(logging);}okHttpClient = builder.build();}}}return okHttpClient;}/*** 動態修改 Base URL*/public static void setBaseUrl(String baseUrl) {retrofit = new Retrofit.Builder().baseUrl(baseUrl).client(getOkHttpClient()).addConverterFactory(GsonConverterFactory.create()).addCallAdapterFactory(RxJava3CallAdapterFactory.create()).build();}/*** 動態修改 OkHttp 配置*/public static void setOkHttpClient(OkHttpClient client) {okHttpClient = client;retrofit = new Retrofit.Builder().baseUrl(retrofit.baseUrl().toString()).client(okHttpClient).addConverterFactory(GsonConverterFactory.create()).addCallAdapterFactory(RxJava3CallAdapterFactory.create()).build();}
}

NetworkHelper:支持自定義錯誤處理器

import io.reactivex.rxjava3.core.Single;
import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers;
import io.reactivex.rxjava3.schedulers.Schedulers;
import io.reactivex.rxjava3.disposables.Disposable;public class NetworkHelper {/*** 發起網絡請求** @param single         RxJava 的 Single 對象* @param successHandler 成功回調* @param errorHandler   失敗回調* @return Disposable 對象,用于取消訂閱*/public static <T> Disposable request(Single<T> single, OnSuccess<T> successHandler, OnError errorHandler) {return single.subscribeOn(Schedulers.io()) // 在 IO 線程執行網絡請求.observeOn(AndroidSchedulers.mainThread()) // 在主線程處理結果.subscribe(successHandler::onSuccess, // 成功回調throwable -> errorHandler.onError(handleError(throwable)) // 失敗回調);}/*** 統一處理錯誤*/private static String handleError(Throwable throwable) {if (throwable instanceof IOException) {return "網絡連接失敗,請檢查網絡設置";} else if (throwable instanceof HttpException) {return "服務器錯誤,請稍后重試";} else {return "未知錯誤:" + throwable.getMessage();}}// 成功回調接口public interface OnSuccess<T> {void onSuccess(T result);}// 失敗回調接口public interface OnError {void onError(String errorMessage);}
}

ApiServiceHelper

import java.lang.reflect.Proxy;public class ApiServiceHelper {/*** 創建 API 服務實例** @param serviceClass API 服務接口類* @return API 服務實例*/public static <T> T createService(Class<T> serviceClass) {return (T) Proxy.newProxyInstance(serviceClass.getClassLoader(),new Class<?>[]{serviceClass},(proxy, method, args) -> {// 通過 Retrofit 創建真正的 API 服務實例T service = RetrofitClient.getRetrofit().create(serviceClass);// 調用方法并返回結果return method.invoke(service, args);});}
}

ApiResponse:統一封裝響應基類

public class ApiResponse<T> {private int code; // 狀態碼private String message; // 消息private T data; // 數據// 無參構造函數public ApiResponse() {}// 全參構造函數public ApiResponse(int code, String message, T data) {this.code = code;this.message = message;this.data = data;}// Getter 和 Setter 方法public int getCode() {return code;}public void setCode(int code) {this.code = code;}public String getMessage() {return message;}public void setMessage(String message) {this.message = message;}public T getData() {return data;}public void setData(T data) {this.data = data;}// toString 方法@Overridepublic String toString() {return "ApiResponse{" +"code=" + code +", message='" + message + '\'' +", data=" + data +'}';}
}

User.java類

public class User {private int id;private String name;private String email;// 無參構造函數public User() {}// 全參構造函數public User(int id, String name, String email) {this.id = id;this.name = name;this.email = email;}// Getter 和 Setter 方法public int getId() {return id;}public void setId(int id) {this.id = id;}public String getName() {return name;}public void setName(String name) {this.name = name;}public String getEmail() {return email;}public void setEmail(String email) {this.email = email;}// toString 方法@Overridepublic String toString() {return "User{" +"id=" + id +", name='" + name + '\'' +", email='" + email + '\'' +'}';}
}

ApiService服務類

import io.reactivex.rxjava3.core.Single;
import okhttp3.MultipartBody;
import okhttp3.ResponseBody;
import retrofit2.http.*;public interface ApiService {// 獲取用戶信息@GET("users/{username}")Single<User> getUser(@Path("username") String username);// 搜索用戶@GET("users/search")Single<List<User>> searchUsers(@Query("query") String query);// 創建用戶@POST("users")Single<User> createUser(@Body User user);// 文件上傳@Multipart@POST("upload")Single<ApiResponse<String>> uploadFile(@Part MultipartBody.Part file);// 文件下載@Streaming@GET("files/{filename}")Single<ResponseBody> downloadFile(@Path("filename") String filename);
}

在業務層調用

public class MainActivity extends AppCompatActivity {private Disposable disposable; // 用于保存 Disposable 對象@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);// 創建 API 服務實例ApiService apiService = ApiServiceHelper.createService(ApiService.class);// 發起網絡請求disposable = NetworkHelper.request(apiService.getUser("john_doe"),user -> {// 處理成功結果Log.d("User", user.toString());},errorMessage -> {// 處理錯誤Log.e("Error", errorMessage);});}@Overrideprotected void onDestroy() {super.onDestroy();// 取消網絡請求,避免內存泄漏if (disposable != null && !disposable.isDisposed()) {disposable.dispose();}}
}

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/897349.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/897349.shtml
英文地址,請注明出處:http://en.pswp.cn/news/897349.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

【nRF52832】【Nodic】開發入門【三】模塊化

title: nRF52832開發入門【二】模塊化 tags: nodic categories: nodic abbrlink: 37752 date: 2025-03-09 17:22:17 1. 介紹 我們實際開發過程中往往會很復雜&#xff0c;為了更好的管理代碼&#xff0c;我們需要模塊化。模塊化的好處有很多&#xff0c;比如&#xff1a; 降…

爬蟲案例八js逆向爬取網易音樂

提示&#xff1a;文章寫完后&#xff0c;目錄可以自動生成&#xff0c;如何生成可參考右邊的幫助文檔 文章目錄 前言一、js逆向的前期準備二、網站分析三、代碼 前言 提示&#xff1a;這里可以添加本文要記錄的大概內容&#xff1a; 爬取網易音樂 提示&#xff1a;以下是本篇…

vue2實現組件庫的自動按需引入,unplugin-auto-import,unplugin-vue-components

1.使用ant-design-vue或者element-ui時&#xff0c;如何每個組件都去import導入組件&#xff0c;大大降低了開發效率&#xff0c;如果全局一次性注冊會增加項目體積&#xff0c;那么如何實現既不局部引入&#xff0c;也不全局注冊&#xff1f; 2.在element-plus官網看到有說明…

【Andrej Karpathy 神經網絡從Zero到Hero】--2.語言模型的兩種實現方式 (Bigram 和 神經網絡)

目錄 統計 Bigram 語言模型質量評價方法 神經網絡語言模型 【系列筆記】 【Andrej Karpathy 神經網絡從Zero到Hero】–1. 自動微分autograd實踐要點 本文主要參考 大神Andrej Karpathy 大模型講座 | 構建makemore 系列之一&#xff1a;講解語言建模的明確入門&#xff0c;演示…

(二 十 二)趣學設計模式 之 備忘錄模式!

目錄 一、 啥是備忘錄模式&#xff1f;二、 為什么要用備忘錄模式&#xff1f;三、 備忘錄模式的實現方式四、 備忘錄模式的優缺點五、 備忘錄模式的應用場景六、 總結 &#x1f31f;我的其他文章也講解的比較有趣&#x1f601;&#xff0c;如果喜歡博主的講解方式&#xff0c;…

安裝SPSS后啟動顯示應用程序無法啟動,因為應用程序的并行配置不正確的解決方案

軟件安裝報錯問題有需要遠程文章末尾獲取聯系方式&#xff0c;可以幫你遠程處理各類安裝報錯。 一、安裝SPSS后啟動顯示應用程序無法啟動&#xff0c;因為應用程序的并行配置不正確報錯 在成功安裝 SPSS 軟件后&#xff0c;嘗試啟動應用程序時&#xff0c;系統彈出錯誤提示窗…

IP,MAC,ARP 筆記

1.什么是IP地址 IP 地址是一串由句點分隔的數字。IP 地址表示為一組四個數字&#xff0c;比如 192.158.1.38 就是一個例子。該組合中的每個數字都可以在 0 到 255 的范圍內。因此&#xff0c;完整的 IP 尋址范圍從 0.0.0.0 到 255.255.255.255。 IP 地址不是隨機的。它們由互…

C++11中的Condition_variable

C11中的condition_variable 在C11中&#xff0c;條件變量&#xff08;std::condition_variable&#xff09;是線程同步機制之一&#xff0c;用于在多線程環境中實現線程間的通信和協調。它允許一個或多個線程在某個條件尚未滿足時等待&#xff0c;直到其他線程通知條件已經滿足…

IO多路復用實現并發服務器

一.select函數 select 的調用注意事項 在使用 select 函數時&#xff0c;需要注意以下幾個關鍵點&#xff1a; 1. 參數的修改與拷貝 readfds 等參數是結果參數 &#xff1a; select 函數會直接修改傳入的 fd_set&#xff08;如 readfds、writefds 和 exceptfds&#xf…

_二級繼電器程控放大倍數自動設置

簡介 在開發項目中&#xff0c;有時會遇到需要使用程控放大的情況&#xff0c;如果沒有opa那種可編程放大器&#xff0c;那么就需要通過繼電器來控制放大倍數。而在繼電器程控中&#xff0c;常用的是二級程控&#xff0c;三級程控相較于二級就復雜了許多。 在二級程控中&#x…

電腦總顯示串口正在被占用處理方法

1.現象 在嵌入式開發過程中&#xff0c;有很多情況下要使用串口調試&#xff0c;其中485/422/232轉usb串口是非常常見的做法。 根據協議&#xff0c;接口芯片不同&#xff0c;需要安裝對應的驅動程序&#xff0c;比如ch340&#xff0c;cp2102&#xff0c;CDM212364等驅動。可…

優雅拼接字符串:StringJoiner 的完整指南

在Java開發中&#xff0c;字符串拼接是高頻操作。無論是日志格式化、構建CSV數據&#xff0c;還是生成動態SQL&#xff0c;開發者常需處理分隔符、前綴和后綴的組合。傳統的StringBuilder雖然靈活&#xff0c;但代碼冗余且易出錯。Java 8推出的StringJoiner類&#xff0c;以簡潔…

LabVIEW閉環控制系統硬件選型與實時性能

在LabVIEW閉環控制系統的開發中&#xff0c;硬件選型直接影響系統的實時性、精度與穩定性。需綜合考慮數據采集速度&#xff08;采樣率、接口帶寬&#xff09;、計算延遲&#xff08;算法復雜度、處理器性能&#xff09;、輸出響應時間&#xff08;執行器延遲、控制周期&#x…

Hive的架構

1. 概念 Hive 是建立在 Hadoop 上的數據倉庫工具&#xff0c;旨在簡化大規模數據集的查詢與管理。它通過類 SQL 語言&#xff08;HiveQL&#xff09;將結構化數據映射為 Hadoop 的 MapReduce&#xff0c;適合離線批處理&#xff0c;尤其適用于數據倉庫場景。 2. 數據模型 表&a…

深入解析:Linux中KVM虛擬化技術

這篇文章將深入分析Linux中虛擬化技術的實現----KVM技術&#xff0c;從KVM技術的簡介、技術架構、以及虛擬機和宿主機交互的重要處理邏輯出發&#xff0c;深入探究KVM技術的實現。 一、KVM簡介&#xff1a; 首先&#xff0c;我們先查看一下KVM架構&#xff0c;看看它的整體工…

golang學習筆記——go語言安裝及系統環境變量設置

文章目錄 go語言安裝go envgo getgoproxy測試安裝 Go 插件安裝 Go 插件依賴工具參考資料用戶環境變量和系統環境變量用戶環境變量系統環境變量示例設置環境變量的步驟設置用戶環境變量設置系統環境變量 驗證環境變量總結 2024年最火的5大Go框架1. Gin&#xff1a;高并發接口的“…

3.6c語言

#define _CRT_SECURE_NO_WARNINGS #include <math.h> #include <stdio.h> int main() {int sum 0,i,j;for (j 1; j < 1000; j){sum 0;for (i 1; i < j; i){if (j % i 0){sum i;} }if (sum j){printf("%d是完數\n", j);}}return 0; }#de…

【TI】如何更改 CCS20.1.0 的 WORKSPACE 默認路徑

參考鏈接&#xff1a; 如何更改 CCS Theia 中工作區的默認位置&#xff1f;- Code Composer Studio 論壇 - Code Composer Studio?? - TI E2E 支持論壇 --- How to change the default location for the workspace in CCS Theia? - Code Composer Studio forum - Code Comp…

Vue3中動態Ref的魔法:綁定與妙用

前言 在Vue 3的開發過程中,動態綁定Ref是一項非常實用的技術,特別是在處理復雜組件結構和動態數據時。通過動態綁定Ref,我們可以更靈活地訪問和操作DOM元素或組件實例,實現更高效的交互和狀態管理。本文將詳細介紹如何在Vue 3中實現動態Ref的綁定,并通過實例展示其妙用。…

CarPlanner:用于自動駕駛大規模強化學習的一致性自回歸軌跡規劃

25年2月來自浙大和菜鳥網絡的論文“CarPlanner: Consistent Auto-regressive Trajectory Planning for Large-scale Reinforcement Learning in Autonomous Driving”。 軌跡規劃對于自動駕駛至關重要&#xff0c;可確保在復雜環境中安全高效地導航。雖然最近基于學習的方法&a…