Android中Retrofit多API接口通用异步调用最优实现方案问询
这种重复编写异步调用逻辑的问题确实很烦人,我之前做Android项目的时候也遇到过,用泛型封装通用请求处理器就能完美解决,不管后续加多少接口,都不用再写重复的enqueue代码了。
解决方案:泛型封装通用异步请求处理
我们可以通过泛型来抽离通用的请求执行逻辑,让所有API接口都能复用同一套异步处理代码,核心思路是把Call的回调逻辑封装成通用方法,适配任意返回类型。
步骤1:定义通用的回调接口
先替换掉原来针对特定数据的ContributorsListener,改成泛型回调,适配所有返回类型:
public interface ApiCallback<T> { // 请求成功时回调,返回解析后的实体类/集合 void onSuccess(T data); // 请求失败时回调,返回错误信息 void onFailure(String errorMessage); }
步骤2:封装通用的Retrofit客户端
把原来分散在GetSensorData里的Retrofit初始化、拦截器配置都移到一个单例客户端类里,同时提供两个核心方法:
createService:获取任意API接口的实例executeCall:执行任意Call请求,并通过通用回调返回结果
public class ApiClient { // 全局单例Retrofit实例 private static final Retrofit retrofit; static { // 配置Gson转换器 Gson gson = new GsonBuilder() .setLenient() .create(); // 配置OkHttpClient,添加统一请求头 OkHttpClient okHttpClient = new OkHttpClient.Builder() .addInterceptor(chain -> { Request original = chain.request(); Request request = original.newBuilder() .addHeader("Accept", "application/json") .addHeader("Authorization", "Bearer " + Common.TOKEN_ACCESS) .method(original.method(), original.body()) .build(); return chain.proceed(request); }) // 可选:添加日志拦截器,方便调试 // .addInterceptor(new HttpLoggingInterceptor().setLevel(HttpLoggingInterceptor.Level.BODY)) .build(); // 初始化Retrofit retrofit = new Retrofit.Builder() .baseUrl(API_BASE_URL) // 替换成你的实际BaseURL .client(okHttpClient) .addConverterFactory(GsonConverterFactory.create(gson)) .build(); } /** * 获取任意API接口的实例 * @param serviceClass API接口的Class对象 * @return 接口实例 */ public static <T> T createService(Class<T> serviceClass) { return retrofit.create(serviceClass); } /** * 通用异步请求执行方法 * @param call Retrofit生成的Call对象 * @param callback 通用回调 * @param <T> 返回数据类型 */ public static <T> void executeCall(Call<T> call, ApiCallback<T> callback) { call.enqueue(new Callback<T>() { @Override public void onResponse(Call<T> call, Response<T> response) { if (response.isSuccessful()) { // 请求成功,返回解析后的实体 callback.onSuccess(response.body()); } else { // 处理非2xx状态码的错误 String errorMsg = response.message().isEmpty() ? "请求失败,状态码:" + response.code() : response.message(); callback.onFailure(errorMsg); } } @Override public void onFailure(Call<T> call, Throwable t) { // 处理网络错误 String errorMsg = t.getMessage() != null ? t.getMessage() : "未知网络错误"; callback.onFailure(errorMsg); } }); } }
步骤3:简化原API接口
把原来GetSensorData里的Retrofit相关配置移除,只保留接口方法即可:
public interface GetSensorData { @GET("data/normal/{station}/{type}/{period}/{duration}") Call<SensorData> getSensorDetails( @Path("station") String station, @Path("type") String type, @Path("period") String period, @Path("duration") String duration ); @GET("user/stations") Call<List<Station>> getStationList(); // 后续新增接口直接在这里添加即可 }
步骤4:使用通用请求处理器
现在不管调用哪个接口,都可以用同一套代码,不用再重复写enqueue逻辑:
// 1. 获取API接口实例 GetSensorData sensorApi = ApiClient.createService(GetSensorData.class); // 2. 调用传感器数据接口 Call<SensorData> sensorCall = sensorApi.getSensorDetails("00000146", "hourly", "last", "5"); ApiClient.executeCall(sensorCall, new ApiCallback<SensorData>() { @Override public void onSuccess(SensorData data) { // 处理成功返回的SensorData数据 Log.d("SensorData", "获取成功:" + data.toString()); } @Override public void onFailure(String errorMessage) { // 处理错误 Log.e("SensorError", "请求失败:" + errorMessage); } }); // 3. 调用站点列表接口(复用同一套逻辑) Call<List<Station>> stationCall = sensorApi.getStationList(); ApiClient.executeCall(stationCall, new ApiCallback<List<Station>>() { @Override public void onSuccess(List<Station> data) { // 处理成功返回的站点列表 Log.d("StationList", "获取成功:" + data.size() + "个站点"); } @Override public void onFailure(String errorMessage) { // 处理错误 Log.e("StationError", "请求失败:" + errorMessage); } });
额外优化(可选)
如果你的项目支持Java 8+,可以用Lambda表达式简化回调代码,让它更简洁:
ApiClient.executeCall(sensorCall, new ApiCallback<>() { @Override public void onSuccess(SensorData data) { // 处理数据 } @Override public void onFailure(String errorMessage) { // 处理错误 } });
如果想进一步简化,还可以结合LiveData或者RxJava来实现响应式的请求处理,但上面的方案已经完全解决了你的核心需求:一套代码处理所有接口的异步请求,后续新增接口只需要在API接口里定义方法,然后重复调用createService和executeCall即可,不用再写任何异步逻辑。
内容的提问来源于stack exchange,提问作者user2908751
相关产品推荐
相关产品推荐

