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、超時時間、攔截器等。
-
統一錯誤處理
增強錯誤處理的靈活性,支持自定義錯誤處理器。 -
支持多環境切換
通過配置文件或 Build Variants 動態切換測試環境和生產環境。 -
添加緩存機制
通過 OkHttp 的緩存攔截器實現本地緩存,減少網絡請求。 -
Token 自動管理
通過攔截器自動添加 Token 并處理 Token 過期。 -
支持文件上傳/下載
擴展 API 服務接口,支持文件操作。 -
日志優化
根據不同的 Build 類型(Debug/Release)動態調整日志級別。 -
生命周期綁定
將網絡請求與 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();}}
}