現在、RxJava と Retrofit を組み合わせて使用することは非常に一般的であると推定されており、私は常に RxJava を仕事で使用してきました。使用するプロセスでは、それをパッケージ化して使用します。GitHub には、直接使用できるパッケージ化されたプロジェクトも多数あります。実際、オープンソース フレームワークの二次パッケージ化は、多かれ少なかれ、別のパッケージ化のプロセスにある場合があります。ビジネスロジックは一部異なるため、自分でパッケージ化して使用することをお勧めします。これにより、元のフレームワークの理解が深まるだけでなく、パッケージ化の能力も向上します。作業中に変更が必要な場合は、この方が簡単に開始できます。さて、早速、参考までに簡単なサンプルを示します。
依存関係を追加する
compile 'com.squareup.retrofit2:retrofit:2.3.0'
compile 'io.reactivex.rxjava2:rxjava:2.x.y'
implementation 'io.reactivex.rxjava2:rxandroid:2.0.2'
implementation 'com.squareup.okhttp3:logging-interceptor:3.10.0'
compile 'com.squareup.retrofit2:converter-gson:2.3.0'
compile 'com.squareup.retrofit2:adapter-rxjava2:2.3.0'
依存関係の追加についてはこれ以上言いません。誰もが知っていると思いますが、私が最初にこの知識に触れたとき、オンライン記事を読んで依存関係を見つけて追加する人はいるだろうかと思いました。たとえば、依存関係com.squareup.retrofit2:converter-gson:2.3.0
を追加したいとしますGsonConverter
。この知識を初めて使用する人や、GitHub にあまりアクセスしない人にとっては混乱するでしょうか? なるかどうかは別として、とにかく最初に触れたときは本当に戸惑いました。ここで混乱している人のために注意してください。GitHub でプロジェクトのサブファイルを開くと、対応する依存関係を確認できます。たとえば、GitHub の Retrofit プロジェクトでは、このパスの下にretrofit/retrofit-converters/gson/
対応する依存関係を表示できますGsonConverter
。
カプセル化レトロフィット (シングルトン モード)
public class HttpRequest {
public static final long CONNECTTIME = 30000;
public static final String BASE_URL = "http://jxhdapi.ooowin.com/";
private ApiService apiService;
public HttpRequest() {
//添加日志拦截器
HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor(new HttpLoggingInterceptor.Logger() {
@Override
public void log(String message) {
Log.d("TAG", "==========" + message);
}
}).setLevel(HttpLoggingInterceptor.Level.BODY);
//获取OkHttpClient
OkHttpClient client = new OkHttpClient.Builder()
.connectTimeout(CONNECTTIME, TimeUnit.MICROSECONDS)
.readTimeout(CONNECTTIME,TimeUnit.MICROSECONDS)
.writeTimeout(CONNECTTIME,TimeUnit.MICROSECONDS)
.addInterceptor(interceptor)
.addNetworkInterceptor(new HttpHeaderInterceptor())
.build();
//初始化Retrofit
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(BASE_URL)
.addConverterFactory(GsonConverterFactory.create())
.addCallAdapterFactory(RxJava2CallAdapterFactory.create())
.client(client)
.build();
apiService = retrofit.create(ApiService.class);
}
// 创建单例
private static class SingletonHolder {
private static final HttpRequest INSTANCE = new HttpRequest();
}
public static ApiService getApi(){
return SingletonHolder.INSTANCE.apiService;
}
}
ここでは、ログ インターセプターとネットワーク リクエスト ヘッダー インターセプターの 2 つのインターセプターが追加されていることがわかります。Retrofit ではエンティティ クラスに直接変換できることは誰もが知っていますが、データを表示するためにその json を取得したい場合もありますGsonConverter
。 , この時点でログインターセプターを追加することで実装できますが、setLevel
そのメソッドを設定する必要があり、異なる属性を設定すると出力されるデータが異なります。ヘッダー インターセプターの追加に関しては、通常の作業でインターフェイスに必要なヘッダーは同じであるため、それらを均一に追加する必要があることは誰もが知っているはずです。
public class HttpHeaderInterceptor implements Interceptor {
@Override
public Response intercept(Chain chain) throws IOException {
Request request = chain.request();
Request build = request.newBuilder()
// .addHeader("","") 添加header
.build();
return chain.proceed(build);
}
}
カプセル化エンティティクラス
{
"code": 1,
"msg": "操作成功",
"data": {······}
}
通常、サーバーから取得する JSON データは上記のようなもので、返されるフィールドのコンテンツ形式の一部は固定されています (コードやメッセージなど)。データなど、不確実なものもあります。この時点で、二次処理を実行する必要があるため、基本クラスを作成できます。
public class BaseBean<T> {
private int code;
private String msg;
private T data;
public int getCode() {
return code;
}
public void setCode(int code) {
this.code = code;
}
public String getMsg() {
return msg;
}
public void setMsg(String msg) {
this.msg = msg;
}
public T getData() {
return data;
}
public void setData(T data) {
this.data = data;
}
}
データ内で不確実な形式でデータを表現するにはジェネリックを使用します。ここでは、国内のすべての州を取得するためのデータ インターフェイスがテストに使用されます。
public interface ApiService {
//获取省列表
@GET("common/areas")
Flowable<BaseBean<List<Province>>> province();
}
エンティティ クラスがカプセル化されたら、テストできます。
HttpRequest.getApi()
.province()
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Subscriber<BaseBean<List<Province>>>() {
@Override
public void onSubscribe(Subscription s) {
}
@Override
public void onNext(BaseBean<List<Province>> listBaseBean) {
}
@Override
public void onError(Throwable t) {
}
@Override
public void onComplete() {
}
});
}
Subscriber
上記のコードを通して、これがカプセル化の効果であることを確認するのは難しくありませんが、そのようなリクエストに対して毎回スケジューラーを追加し、いくつかのメソッドを書き直す必要があることがわかります。それはまだ面倒ではないでしょうか。はい、これらをカプセル化します。
作成演算子を使用する
public class SchedulersHelper implements FlowableTransformer{
@Override
public Publisher apply(Flowable upstream) {
return upstream.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread());
}
}
compose オペレーターを使用すると、現在の Flowable を直接操作できるため、ここにスレッドを切り替える操作を自然に追加できます。次のステップは、カプセル化のためのサブスクライバです。
パッケージ購読者
public abstract class MySubscriber<T> implements Subscriber<T>{
@Override
public void onSubscribe(Subscription s) {
s.request(Long.MAX_VALUE);
showLoading();
}
@Override
public void onNext(T t) {
//code为1代表服务器返回成功的数据
if (((BaseBean)t).getCode() == 1) {
//成功后返回data数据进行处理即可
onSuccess((T) ((BaseBean) t).getData());
}else {
//处理服务器返回错误code
}
}
@Override
public void onComplete() {
finishLoading();
}
@Override
public void onError(Throwable t) {
finishLoading();
//处理网络异常
Log.d("TAG","=========" + t);
}
protected abstract void onSuccess(T t);
protected abstract void showLoading();
protected abstract void finishLoading();
}
上記のように、サーバーから返されたコードに基づいて成功したかどうかを判断し、データを送信します。サーバーから返されたエラー コードとネットワーク リクエスト エラーはすべて、ここで統一された方法で処理できます。次に、インターフェイスのテストに進みます。
テスト
HttpRequest.getApi().province()
.compose(new SchedulersHelper())
.subscribe(new MySubscriber() {
@Override
protected void onSuccess(Object o) {
}
@Override
protected void showLoading() {
}
@Override
protected void finishLoading() {
}
});
動作プロセスが非常にシンプルになっていることがわかりますが、showLoading()
このfinishLoading()
2 つのメソッドはここに記述する必要はなく、テストの便宜のために記載されています。
終了
この時点で、RxJava + Retrofit のカプセル化は完了しました。これは、あまり複雑なロジックを使用しない、非常に単純なカプセル化プロセスです。比較的分かりやすく、パッケージの完成度はそれほど高くないかもしれませんが、参考にして自分なりの理解を深めてパッケージ化していただければと思います。以前に簡単な MVP 基本クラスを作成し、このカプセル化プロセスのために前のプロジェクトにそれを入れました。シンプルで分かりやすく使いやすい RxJava + Retrofit + MVP の小さなデモを GitHub に公開しており、 RxRetrofitMvp を確認することができます。役に立ったと思ったら、星を付けてください、ははは!