安卓网络请求 OkHttp & Retrofit

一、仅使用 OkHttp

1. 依赖

dependencies {
    //网络请求
    implementation "com.squareup.okhttp3:okhttp:4.9.3"
}
gradle

2. 主要实现——工具类

package cool.hyz.xujiayi.utils;

import com.google.gson.Gson;

import java.io.IOException;
import java.math.BigInteger;
import java.net.URLEncoder;
import java.security.MessageDigest;
import java.util.Date;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Objects;

import okhttp3.MediaType;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;

/**
 * Created by Lib on 2022/4/20
 * Best Wishes !
 */

public class HttpRequest {
    public static final MediaType JSON = MediaType.parse("application/json; charset=utf-8");
    OkHttpClient client = new OkHttpClient();

    /**
     * POST请求
     */
    public String POST(String url, String json) throws IOException {
        Response response;
        RequestBody body = RequestBody.create(JSON, json);
        Map<String, String> lockData = lockData(url);
        Request request = new Request.Builder()
                .url(url)
                .post(body)
                .build();
        response = client.newCall(request).execute();
        if (response.isSuccessful()) {
            return Objects.requireNonNull(response.body()).string();
        } else {
            throw new IOException("Unexpected code " + response);
        }
    }

    /**
     * GET请求
     */
    public String GET(String url) throws IOException {
        Map<String, String> lockData = lockData(url);
        Request request = new Request.Builder()
                .url(url)
                .build();
        Response response = client.newCall(request).execute();
        if (response.isSuccessful()) {
            return Objects.requireNonNull(response.body()).string();
        } else {
            throw new IOException("Unexpected code " + response);
        }
    }

}
java

3. 调用方法

例如在Presenter中发起请求,返回结果后通知UI更新

package cool.hyz.xujiayi.services;

import com.google.gson.Gson;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import cool.hyz.xujiayi.services.interfaces.IArticleDetailPresenter;

import cool.hyz.xujiayi.beans.ArticleDetailBean;
import cool.hyz.xujiayi.beans.CommentListBean;

import cool.hyz.xujiayi.utils.Constance;
import cool.hyz.xujiayi.utils.HttpRequest;

/**
 * Created by Lib on 2022/4/20
 * Best Wishes !
 */

public class ArticleDetailPresenter implements IArticleDetailPresenter {

    private IArticleDetailPresenterCallback mCallback;

    HttpRequest request = new HttpRequest();

    @Override
    public void getArticleInfo(String id) {

        new Thread(() -> {
            ArticleDetailBean articleDetail = null;
            try {
                articleDetail = new Gson().fromJson(request.GET(Constance.API.ARTICLE_DETAIL+id), ArticleDetailBean.class);
            } catch (IOException e) {
                e.printStackTrace();
            }

            mCallback.onArticleInfoLoaded(articleDetail);
        }).start();

    }
}
java

二、使用 OkHttp & Retrofit

1. 依赖

dependencies {
    //网络请求
    implementation "com.squareup.okhttp3:okhttp:4.9.3"
    implementation "com.squareup.retrofit2:retrofit:2.9.0"
    implementation "com.squareup.retrofit2:converter-gson:2.9.0"
}
gradle

2. 主要实现

  • retrofit客户端——RetrofitClient
package cool.hyz.xujiayi.api;

import java.util.Map;
import java.util.Objects;
import java.util.concurrent.TimeUnit;

import okhttp3.OkHttpClient;
import okhttp3.Request;
import retrofit2.Retrofit;
import retrofit2.converter.gson.GsonConverterFactory;

/**
 * @author xujiayi
 * @date 2023/11/6
 * 我只是个自由的主!
 */
public class RetrofitClient {

    public static final String TAG = "RetrofitClient";
    
    //mOkHttpClient
    private final OkHttpClient mOkHttpClient = new OkHttpClient.Builder()
            .addInterceptor(chain -> {
                //拦截处理(非必须)
                //TODO:添加header信息
                Request newRequest = chain.request().newBuilder()
                        .header("header1", "header")
                        .header("header2", "header")
                        .build();

                return chain.proceed(newRequest);
            })
            .callTimeout(30, TimeUnit.SECONDS)
            .build();
    
    //Retrofit
    private final Retrofit mRetrofit = new Retrofit.Builder()
            .baseUrl(ApiService.BASE_URL)
            .addConverterFactory(GsonConverterFactory.create())
            .client(mOkHttpClient)
            .build();
    
    public final ApiService apiService = mRetrofit.create(ApiService.class);

}
java
  • ApiService.java
package cool.hyz.xujiayi.api;

import java.util.List;

import cool.hyz.xujiayi.beans.Article;
import cool.hyz.xujiayi.beans.Result;
import cool.hyz.xujiayi.utils.Constance;
import retrofit2.Call;
import retrofit2.http.GET;
import retrofit2.http.Query;

/**
 * @author xujiayi
 * @date 2023/11/6
 * 我只是个自由的主!
 */
public interface ApiService {
    String BASE_URL = "http://localhost:1314/api/";

    @GET("/article)
    Call<Result<List<Article>>> getArticleList(@Query("current") int current);
}

java
  • 请求结果模板类——Result.java
package cool.hyz.xujiayi.beans;

import android.util.Log;

import cool.hyz.xujiayi.api.ApiException;

/**
 * @author xujiayi
 * @date 2023/11/6
 * 我只是个自由的主!
 */
public class Result<T> {

    public static final String TAG = "Result";
    private final boolean flag;
    private final int code;
    private final String message;
    private final T data;

    private static final int SUCCESS_CODE = 20000;

    public Result(boolean flag, int code, String message, T data) {
        this.flag = flag;
        this.code = code;
        this.message = message;
        this.data = data;
    }

    public T getData() {

        Log.d(TAG, "getData: "+message);
        //成功才返回数据
        if (code == SUCCESS_CODE)
            return data;
        else throw new ApiException(code, message);
    }
}
java
  • 返回数据模板类——Article.java
package cool.hyz.xujiayi.beans;

import java.util.List;

/**
 * @author xujiayi
 * @date 2023/11/6
 * 我只是个自由的主!
 */

public class Article {

        private int id;
        private String articleCover;
        private String articleTitle;
        private String createTime;

        public int getId() {
            return id;
        }

        public void setId(int id) {
            this.id = id;
        }

        public String getArticleCover() {
            return articleCover;
        }

        public void setArticleCover(String articleCover) {
            this.articleCover = articleCover;
        }

        public String getArticleTitle() {
            return articleTitle;
        }

        public void setArticleTitle(String articleTitle) {
            this.articleTitle = articleTitle;
        }
}
java

3. 使用方法

例如,在ViewModel中调用

package cool.hyz.xujiayi.views.models;

import android.util.Log;
import androidx.lifecycle.ViewModel;
import java.util.List;
import cool.hyz.xujiayi.beans.Article;

/**
 * @author xujiayi
 * @date 2023/11/6
 * 我只是个自由的主!
 */
public class HomeViewModel extends ViewModel {

    public static final String TAG = "HomeViewModel";

    public void listArticles(int current){
        new RetrofitClient().apiService.getArticleList(current).enqueue(new Callback<Result<List<Article>>>() {
            @Override
            public void onResponse(Call<Result<List<Article>>> call, Response<Result<List<Article>>> response) {
                Log.d(TAG, "onResponse: " + ((List<Article>) response.body().getData()).size());
                Log.d(TAG, "onResponse: " + ((List<Article>) response.body().getData()).get(0).getArticleTitle());
            }

            @Override
            public void onFailure(Call<Result<List<Article>>> call, Throwable t) {
                Log.d(TAG, "onFailure: " + t.getMessage());
                t.printStackTrace();
            }
        });
    }
}
java

三、进阶 —— OkHttp & Retrofit & Rxjava

1. 依赖

dependencies {
    //网络请求
    implementation "com.squareup.okhttp3:okhttp:4.9.3"
    implementation "com.squareup.retrofit2:retrofit:2.9.0"
    implementation "com.squareup.retrofit2:converter-gson:2.9.0"
    implementation "com.squareup.retrofit2:adapter-rxjava3:2.9.0"
}
gradle

2. 主要实现

  • 修改RetrofitClient.java
package cool.hyz.xujiayi.api;
...

import retrofit2.adapter.rxjava3.RxJava3CallAdapterFactory;

/**
 * @author xujiayi
 * @date 2023/11/6
 * 我只是个自由的主!
 */
public class RetrofitClient {
    ...

    //Retrofit
    private final Retrofit mRetrofit = new Retrofit.Builder()
            .baseUrl(ApiService.BASE_URL)
            .addConverterFactory(GsonConverterFactory.create())
            .addCallAdapterFactory(RxJava3CallAdapterFactory.create())
            .client(mOkHttpClient)
            .build();
    ...
}
java
  • 修改ApiService.java——使用Observable
package cool.hyz.xujiayi.api;
...

import io.reactivex.rxjava3.core.Observable;

/**
 * @author xujiayi
 * @date 2023/11/6
 * 我只是个自由的主!
 */
public interface ApiService {
    ...
    
    @GET(Constance.API.ARTICLES)
    Observable<Result<List<Article>>> getArticleListInfo(@Query("current") int current);
}
java

3. 使用方法

例如,在ViewModel中调用

package cool.hyz.xujiayi.views.models;

import android.util.Log;

import java.util.List;

import cool.hyz.xujiayi.api.RetrofitClient;
import cool.hyz.xujiayi.beans.Article;
import io.reactivex.rxjava3.disposables.CompositeDisposable;
import io.reactivex.rxjava3.disposables.Disposable;

/**
 * @author xujiayi
 * @date 2023/11/6
 * 我只是个自由的主!
 */
public class HomeViewModel extends ViewModel {

    public static final String TAG = "HomeViewModel";

    public void listArticles(int current){
        CompositeDisposable compositeDisposable = new CompositeDisposable();

        Disposable subscribe = new RetrofitClient().apiService.getArticleListInfo(current).subscribe(
                list -> {
                    //处理成功结果
                    Log.d(TAG, "getArticleList: Success->" + list.getData().size());
                    Log.d(TAG, "getArticleList: Success->" + list.getData().get(0).getArticleTitle());
                },
                throwable -> {
                    //处理失败结果
                    Log.d(TAG, "getArticleList: Failed->" + throwable.getMessage());
                    throwable.printStackTrace();
                });
        compositeDisposable.add(subscribe);
    }
}
java

这样就很清晰了

不过其实上面的是使用了lambda表达式简化后的结果,简化前:

package cool.hyz.xujiayi.views.models;

import android.util.Log;

import java.util.List;

import cool.hyz.xujiayi.api.RetrofitClient;
import cool.hyz.xujiayi.beans.Article;
import io.reactivex.rxjava3.disposables.CompositeDisposable;
import io.reactivex.rxjava3.disposables.Disposable;

/**
 * @author xujiayi
 * @date 2023/11/6
 * 我只是个自由的主!
 */
public class HomeViewModel extends ViewModel {

    public static final String TAG = "HomeViewModel";

    public void listArticles(int current){
        CompositeDisposable compositeDisposable = new CompositeDisposable();

        Disposable subscribe = new RetrofitClient().apiService.getArticleListInfo(current).subscribe(
                new Consumer<Result<List<Article>>>() {
                    @Override
                    public void accept(Result<List<Article>> list) throws Throwable {
                        //处理成功结果
                        Log.d(TAG, "getArticleList: Success->" + list.getData().size());
                        Log.d(TAG, "getArticleList: Success->" + list.getData().get(0).getArticleTitle());

                    }
                },
                new Consumer<Throwable>() {
                    @Override
                    public void accept(Throwable throwable) throws Throwable {
                        //处理失败结果
                        Log.d(TAG, "getArticleList: Failed->" + throwable.getMessage());
                        throwable.printStackTrace();
                    }
                }
        );
        compositeDisposable.add(subscribe);
    }
}
java

4. 切换线程

  • 补充依赖
dependencies {
    //RxAndroid
    implementation 'io.reactivex.rxjava3:rxandroid:3.0.2'
}
gradle
  • 使用方法
package cool.hyz.xujiayi.views.models;

...
import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers;
import io.reactivex.rxjava3.schedulers.Schedulers;

/**
 * @author xujiayi
 * @date 2023/11/6
 * 我只是个自由的主!
 */
public class HomeViewModel extends ViewModel {
    ...

    public void listArticles(int current){
        CompositeDisposable compositeDisposable = new CompositeDisposable();

        Disposable subscribe = new RetrofitClient().apiService.getArticleList(current)
                .subscribeOn(Schedulers.io())//子线程
                .observeOn(AndroidSchedulers.mainThread())//主线程
                .subscribe(list -> {list -> {
                    //处理成功结果
                    Log.d(TAG, "getArticleList: Success->" + list.getData().size());
                    Log.d(TAG, "getArticleList: Success->" + list.getData().get(0).getArticleTitle());
                },throwable -> {
                    //处理失败结果
                    Log.d(TAG, "getArticleList: Failed->" + throwable.getMessage());
                    throwable.printStackTrace();
                });
        compositeDisposable.add(subscribe);
    }
}
java

四、高阶——注解

1. 添加Hilt插件

使用 Hilt 实现依赖项注入

HiltAndroid 的依赖项注入库,可减少在项目中执行手动依赖项注入的样板代码。执行手动依赖项注入要求您手动构造每个类及其依赖项,并借助容器重复使用和管理依赖项。

  • build.gradle
...

plugins {
    id 'com.google.dagger.hilt.android' version '2.42' apply false
}

- `app/build.gradle`
```groovy
...
apply plugin: 'com.google.dagger.hilt.android'

...

dependencies {
    //hilt
    implementation "com.google.dagger:hilt-android:2.42"
    annotationProcessor "com.google.dagger:hilt-android-compiler:2.42"
}
groovy

2. 创建Application并添加注解

  • 创建BaseApllicaiton并添加注解
package cool.hyz.xujiayi.bases;

import android.app.Application;
import dagger.hilt.android.HiltAndroidApp;

/**
 * @author xujiayi
 * @date 2023/11/5
 * 我只是个自由的主!
 */
@HiltAndroidApp
public class BaseApplication extends Application {

    @Override
    public void onCreate() {
        super.onCreate();
    }
}
java
  • AndroidManifest.xml注册
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="cool.hyz.xujiayi"
    android:versionName="1.0.0">
    ...
    <application
        android:name=".bases.BaseApplication"
        ...
        >
        ...
    </application>
</manifest>
xml

3. 创建Module

  • ApiModule.java
package cool.hyz.xujiayi.api;

import java.util.Map;
import java.util.Objects;
import java.util.concurrent.TimeUnit;
import javax.inject.Singleton;

import dagger.Module;
import dagger.Provides;
import dagger.hilt.InstallIn;
import dagger.hilt.components.SingletonComponent;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import retrofit2.Retrofit;
import retrofit2.adapter.rxjava3.RxJava3CallAdapterFactory;
import retrofit2.converter.gson.GsonConverterFactory;

/**
 * @author xujiayi
 * @date 2023/11/7
 * 我只是个自由的主!
 */
@InstallIn(SingletonComponent.class)
@Module
public class ApiModule {
    /**
     * OkHttpClient
     * @return OkHttpClient
     */
    @Singleton //单例
    @Provides
    OkHttpClient provideOkHttpClient(){
        return new OkHttpClient.Builder()
            .addInterceptor(chain -> {
                //拦截处理(非必须)
                //TODO:添加header信息
                Request newRequest = chain.request().newBuilder()
                        .header("header1", "header")
                        .header("header2", "header")
                        .build();
                return chain.proceed(newRequest);
            })
            .callTimeout(30, TimeUnit.SECONDS)
            .build();
    }

    /**
     * Retrofit
     * @param okHttpClient OkHttpClient
     * @return Retrofit
     */
    @Singleton //单例
    @Provides
    Retrofit provideRetrofitClient(OkHttpClient okHttpClient){
        return new Retrofit.Builder()
                .baseUrl(ApiService.BASE_URL)
                .addConverterFactory(GsonConverterFactory.create())
                .addCallAdapterFactory(RxJava3CallAdapterFactory.create())
                .client(okHttpClient)
                .build();
    }

    /**
     * ApiService
     * @param retrofitClient Retrofit
     * @return ApiService
     */
    @Singleton //单例
    @Provides
    ApiService provideApiService(Retrofit retrofitClient){
        return retrofitClient.create(ApiService.class);
    }
}
java

4. 使用

使用@AndroidEntryPoint注解定义可注入入口,使用@Inject注解获取实例

package cool.hyz.xujiayi;

import androidx.appcompat.app.AppCompatActivity;

import javax.inject.Inject;

import dagger.hilt.android.AndroidEntryPoint;
import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers;
import io.reactivex.rxjava3.disposables.CompositeDisposable;
import io.reactivex.rxjava3.disposables.Disposable;
import io.reactivex.rxjava3.schedulers.Schedulers;

@AndroidEntryPoint //声明可注入入口
public class MainActivity extends AppCompatActivity {
    public static final String TAG = "MainActivity";

    private int current = 1;

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

        getArticleList(current);
    }

    @Inject
    ApiService mApiService;

    public void getArticleList(int current) {
        CompositeDisposable compositeDisposable = new CompositeDisposable();

        Disposable subscribe = mApiService.getArticleList(current)
                .subscribeOn(Schedulers.io())//子线程
                .observeOn(AndroidSchedulers.mainThread())//主线程
                .subscribe(list -> {
                    //处理成功结果
                    Log.d(TAG, "getArticleList: Success->" + list.getData().size());
                    Log.d(TAG, "getArticleList: Success->" + list.getData().get(0).getArticleTitle());
                }, throwable -> {
                    //处理失败结果
                    Log.d(TAG, "getArticleList: Failed->" + throwable.getMessage());
                    throwable.printStackTrace();
                });
        compositeDisposable.add(subscribe);
    }
}
java

注意

Hilt 提供的 @AndroidEntryPoint 注解用于提供 Android 类的依赖(Activity、Fragment、View、Service、BroadcastReceiver)特殊的 Application 使用 @HiltAndroidApp 注解。

Activity:仅支持 ComponentActivity 的子类例如 FragmentActivity、AppCompatActivity 等等。
Fragment:仅支持继承 androidx.Fragment 的 Fragment
View
Service
BroadcastReceiver
坑:
如果使用 @AndroidEntryPoint 在非 ComponentActivity 子类上注解,例如 Activity 则会抛出异常。

另外java版本为11

五、高阶——封装

1. ApiException

package cool.hyz.xujiayi.api.exception;

import android.net.ParseException;
import com.google.gson.JsonParseException;
import org.json.JSONException;

import java.net.ConnectException;
import java.net.SocketTimeoutException;
import java.net.UnknownHostException;

/**
 * @author xujiayi
 * @date 2023/11/7
 * 我只是个自由的主!
 */

/**
 * 通用异常封装
 */
public class ApiException extends Exception {
    private static final int UNKNOWN_ERROR = 1000;
    private static final int PARSE_ERROR = 1001;
    private static final int NETWORK_ERROR = 1002;
    private String message;

    private int code;

    public ApiException(int code, String message) {
        this.message = message;
        this.code = code;
    }

    public static ApiException handleException(Throwable e) {
        ApiException ex;
        if (e instanceof JsonParseException || e instanceof JSONException
                || e instanceof ParseException) {
            ex = new ApiException(PARSE_ERROR, "数据解析异常" );
            return ex;
        } else if (e instanceof ConnectException
                || e instanceof UnknownHostException || e instanceof SocketTimeoutException) {
            ex = new ApiException(NETWORK_ERROR, "网络请求异常" );
            return ex;
        } else {
            ex = new ApiException(UNKNOWN_ERROR, "未知异常" );
            return ex;
        }
    }
}
java

2. ErrorComsumer

package cool.hyz.xujiayi.api.exception;

import io.reactivex.rxjava3.functions.Consumer;

/**
 * @author xujiayi
 * @date 2023/11/7
 * 我只是个自由的主!
 */

/**
 * 异常处理Consumer
 */
public abstract class ErrorComsumer implements Consumer<Throwable> {
    @Override
    public void accept(Throwable throwable) throws Throwable {
        ApiException exception;
        if(throwable instanceof ApiException){
            exception = (ApiException) throwable;
        }else {
            exception = ApiException.handleException(throwable);
        }
        error(exception);
    }

    protected abstract void error(ApiException exception);
}
java

3. IResponse

package cool.hyz.xujiayi.api.response;

/**
 * @author xujiayi
 * @date 2023/11/7
 * 我只是个自由的主!
 */
public interface IResponse<T> {
    /**
     * 是否成功
     */
    boolean isSuccess();

    /**
     * 获取数据
     * @return T
     */
    T getData();

    /**
     * 状态码
     */
    int getCode();
    /**
     * 失败信息
     */
    String getMessage();

}
java

4. 实现IResponse

package cool.hyz.xujiayi.beans;

import android.util.Log;
import cool.hyz.xujiayi.api.response.IResponse;

/**
 * @author xujiayi
 * @date 2023/11/6
 * 我只是个自由的主!
 */
public class Result<T> implements IResponse<T> {

    public static final String TAG = "Result";
    private final boolean flag;
    private final int code;
    private final String message;
    private final T data;

    private static final int SUCCESS_CODE = 20000;

    public Result(boolean flag, int code, String message, T data) {
        this.flag = flag;
        this.code = code;
        this.message = message;
        this.data = data;
    }

    @Override
    public boolean isSuccess() {
        return code == SUCCESS_CODE;
    }

    @Override
    public T getData() {

        Log.d(TAG, "getData: "+message);
        //成功,返回数据
        if (code == SUCCESS_CODE)
            return data;
        else return null;
    }

    @Override
    public int getCode() {
        return code;
    }

    @Override
    public String getMessage() {
        return message;
    }
}
java

5. ResponseTransformer

package cool.hyz.xujiayi.api.response;

import cool.hyz.xujiayi.api.exception.ApiException;
import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers;
import io.reactivex.rxjava3.annotations.NonNull;
import io.reactivex.rxjava3.core.Observable;
import io.reactivex.rxjava3.core.ObservableSource;
import io.reactivex.rxjava3.core.ObservableTransformer;
import io.reactivex.rxjava3.disposables.CompositeDisposable;
import io.reactivex.rxjava3.disposables.Disposable;
import io.reactivex.rxjava3.functions.Consumer;
import io.reactivex.rxjava3.functions.Function;
import io.reactivex.rxjava3.schedulers.Schedulers;

/**
 * @author xujiayi
 * @date 2023/11/7
 * 我只是个自由的主!
 */
public class ResponseTransformer<T> implements ObservableTransformer<IResponse<T>, T> {

    private CompositeDisposable mCompositeDisposable;

    public ResponseTransformer() {

    }

    public ResponseTransformer(CompositeDisposable compositeDisposable) {
        this.mCompositeDisposable = compositeDisposable;
    }

    @Override
    public @NonNull ObservableSource<T> apply(@NonNull Observable<IResponse<T>> upstream) {
        return upstream
                .doOnSubscribe(new Consumer<Disposable>() {
                    @Override
                    public void accept(Disposable disposable) throws Throwable {
                        //生命周期相关
                        if (mCompositeDisposable != null) {
                            mCompositeDisposable.add(disposable);
                        }
                    }
                })
                .onErrorResumeNext(new Function<Throwable, ObservableSource<? extends IResponse<T>>>() {
                    @Override
                    public ObservableSource<? extends IResponse<T>> apply(Throwable throwable) throws Throwable {
                        //异常后的统一处理
                        return Observable.error(ApiException.handleException(throwable));
                    }
                })
                .flatMap(new Function<IResponse<T>, ObservableSource<? extends T>>() {
                    @Override
                    public ObservableSource<? extends T> apply(IResponse<T> response) throws Throwable {
                        //请求完成后,根据返回的数据做统一处理
                        if (response.isSuccess()) {
                            if (response.getData() != null) {
                                return Observable.just(response.getData());
                            } else {
                                //数据为空
                                try {
                                    T instance = getInstance((Class<T>) response.getClass().getTypeParameters()[0].getClass());
                                    return Observable.just(instance);
                                }catch (Exception e){
                                    e.printStackTrace();
                                }
                            }
                        }
                        return Observable.error(new ApiException(response.getCode(),response.getMessage()));
                    }
                })
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread());
    }

    /**
     * 获取泛型实例
     * @param clt Class<T> 
     * @return T
     * @throws Exception Exception
     */
    private T getInstance(Class<T> clt) throws Exception {
        return clt.newInstance();
    }

    /**
     * 获取ResponseTransformer
     * @param compositeDisposable CompositeDisposable
     * @return ResponseTransformer<U>
     * @param <U>  <U>
     */
    public static <U> ResponseTransformer<U> obtain(CompositeDisposable compositeDisposable){
        return new ResponseTransformer<>(compositeDisposable);
    }

    /**
     * 获取ResponseTransformer
     * @return ResponseTransformer<U>
     * @param <U>  <U>
     */
    public static <U> ResponseTransformer<U> obtain(){
        return new ResponseTransformer<>();
    }
}
java

6. 修改ApiService

package cool.hyz.xujiayi.api;
...

public interface ApiService {
    ...

    @GET(Constance.API.ARTICLES)
    Observable<Result<List<Article>>> getArticleList(@Query("current") int current);
}
java

7. 使用


package cool.hyz.xujiayi;

import androidx.appcompat.app.AppCompatActivity;

import javax.inject.Inject;

import dagger.hilt.android.AndroidEntryPoint;
import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers;
import io.reactivex.rxjava3.disposables.CompositeDisposable;
import io.reactivex.rxjava3.disposables.Disposable;
import io.reactivex.rxjava3.schedulers.Schedulers;

@AndroidEntryPoint //声明可注入入口
public class MainActivity extends AppCompatActivity {
    public static final String TAG = "MainActivity";

    private int current = 1;

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

        getArticleList(current);
    }

    @Inject
    ApiService mApiService;

    public void getArticleList(int current) {
        mApiService.getArticleList(current)
                .compose(ResponseTransformer.obtain())
                .subscribe(
                        new Consumer<List<Article>>() {
                            @Override
                            public void accept(List<Article> list) throws Throwable {
                                //处理成功结果
                                Log.d(TAG, "getArticleList: Success->" + list.size());
                                Log.d(TAG, "getArticleList: Success->" + list.get(0).getArticleTitle());
                            }
                        },
                        new ErrorComsumer() {
                            @Override
                            protected void error(ApiException exception) {
                                //处理失败结果
                                Log.d(TAG, "getArticleList: Failed->" + exception.getMessage());
                                exception.printStackTrace();
                            }
                        })
                .disposed();
    }
}
java
打赏
  • 微信
  • 支付宝
评论
来发评论吧~
···

歌手: