likes
comments
collection
share

Retrofit2+RxJava2 实践

作者站长头像
站长
· 阅读数 42

Retrofit2+RxJava2 实践

文章非原创,是对他人文章的实践、参考和整理。

参考链接:

  1. www.jianshu.com/p/3886bc39f… (CompositeDisposable概念)
  2. github.com/WuXiaolong/… (易懂的源码)

前两篇介绍了简单的用法,现在结合起来用。

准备工作

理解概念

前面的例子中的观察者是Observer,这篇文章封装的时候用的是DisposableObserver+CompositeDisposable,是为了让观察者管理起来更方便。 应用文章

  • 如果Activity要被销毁时,我们的后台任务没有执行完,那么就会导致Activity不能正常回收。
  • 而对于每一个DisposableObserver,都会有一个Disposable对象用于管理。
  • RxJava提供了一个CompositeDisposable类用于管理这些Disposable,我们只需要将其将入到该集合当中。
  • 在Activity的onDestroy方法中,调用它的clear方法,就能避免内存泄漏的发生。

引入依赖

    // retrofit2
    implementation 'com.squareup.retrofit2:retrofit:2.5.0'
    implementation 'com.squareup.retrofit2:converter-gson:2.5.0'
    implementation 'com.squareup.retrofit2:adapter-rxjava2:2.5.0'
    // rxjava2
    implementation 'io.reactivex.rxjava2:rxjava:2.1.0'
    implementation 'io.reactivex.rxjava2:rxandroid:2.1.0'
    implementation 'com.squareup.okhttp3:logging-interceptor:3.9.1'

类分析

一共有六个类。

  • ApiService: 域名+访问接口
  • ApiClient: 创建Retrofit
  • ApiCallback: 公共处理返回值,处理错误信息的类
  • BaseActivity: 管理观察者,提供订阅方法
  • MainActivity:操作界面
  • PlayListInfo:歌单实体类

ApiService

import java.util.Map;
import io.reactivex.Observable;
import retrofit2.http.GET;
import retrofit2.http.QueryMap;

public interface ApiService {
    /*主域名,用某狗音乐举例*/
    String API_SERVER_URL = "https://m.kugou.com/plist/";

    /*多个参数*/
    @GET("index")
    Observable<PlayListInfo> getPlayList(@QueryMap Map<String, String> options);
}

ApiClient

import okhttp3.OkHttpClient;
import okhttp3.logging.HttpLoggingInterceptor;
import retrofit2.Retrofit;
import retrofit2.adapter.rxjava2.RxJava2CallAdapterFactory;
import retrofit2.converter.gson.GsonConverterFactory;

class ApiClient {

    public static Retrofit mRetrofit;

    public static Retrofit retrofit() {
        if (mRetrofit == null) {
            OkHttpClient.Builder builder = new OkHttpClient.Builder();

            if (BuildConfig.DEBUG) {
                // Log信息拦截器
                HttpLoggingInterceptor loggingInterceptor = new HttpLoggingInterceptor();
                loggingInterceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
                //设置 Debug Log 模式
                builder.addInterceptor(loggingInterceptor);
            }

            OkHttpClient okHttpClient = builder.build();
            // 创建 retrofit
            mRetrofit = new Retrofit.Builder()
                    .baseUrl(ApiService.API_SERVER_URL)
                    .addConverterFactory(GsonConverterFactory.create())
                    .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
                    .client(okHttpClient)
                    .build();
        }
        return mRetrofit;
    }
}

ApiCallback

import io.reactivex.observers.DisposableObserver;
import retrofit2.HttpException;

abstract class ApiCallback<M> extends DisposableObserver<M> {

    public abstract void onSuccess(M model);

    public abstract void onFailure(String msg);

    public abstract void onFinish();

    @Override
    public void onError(Throwable e) {
        e.printStackTrace();
        if (e instanceof HttpException) {
            HttpException httpException = (HttpException) e;
            //httpException.response().errorBody().string()
            int code = httpException.code();
            String msg = httpException.getMessage();
            if (code == 504) {
                msg = "网络不给力";
            }
            if (code == 502 || code == 404) {
                msg = "服务器异常,请稍后再试";
            }
            onFailure(msg);
        } else {
            onFailure(e.getMessage());
        }
        onFinish();
    }

    @Override
    public void onNext(M model) {
        onSuccess(model);

    }

    @Override
    public void onComplete() {
        onFinish();
    }

}

BaseActivity

import android.app.Activity;

import io.reactivex.Observable;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.disposables.CompositeDisposable;
import io.reactivex.observers.DisposableObserver;
import io.reactivex.schedulers.Schedulers;

class BaseActivity extends Activity {

    private CompositeDisposable mCompositeDisposable;

    public ApiService apiService() {
        return ApiClient.retrofit().create(ApiService.class);
    }

    @Override
    protected void onDestroy() {
        onUnsubscribe();
        super.onDestroy();
    }

    /**
     * 订阅
     *
     * @param observable 被观察者
     * @param observer   观察者
     */
    public <T> void addSubscription(Observable<T> observable, DisposableObserver<T> observer) {
        if (mCompositeDisposable == null) {
            mCompositeDisposable = new CompositeDisposable();
        }
        mCompositeDisposable.add(observer);

        observable.subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(observer);
    }
    
    public void onUnsubscribe() {
        //取消注册,以避免内存泄露
        if (mCompositeDisposable != null)
            mCompositeDisposable.dispose();
    }

}

MainActivity

import android.os.Bundle;
import android.util.Log;
import android.view.View;

import java.util.HashMap;
import java.util.Map;

public class MainActivity extends BaseActivity {

    final String TAG = "MainActivity";

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

    public void TEST(View view) {
        Map<String, String> options = new HashMap<>();
        options.put("json", "true");
        options.put("page", "1");

        addSubscription(apiService().getPlayList(options), new ApiCallback<PlayListInfo>() {
            @Override
            public void onSuccess(PlayListInfo model) {
                if (model != null)
                    Log.d(TAG, "访问成功:" + model.getSrc());
            }

            @Override
            public void onFailure(String msg) {
                Log.d(TAG, "访问失败:" + msg);
            }

            @Override
            public void onFinish() {
                Log.d(TAG, "完成");
            }
        });
    }
}

PlayListInfo (自定义的歌单对象)

class PlayListInfo {

    private String kg_domain;
    private String src;

    public String getKg_domain() {
        return kg_domain;
    }

    public void setKg_domain(String kg_domain) {
        this.kg_domain = kg_domain;
    }

    public String getSrc() {
        return src;
    }

    public void setSrc(String src) {
        this.src = src;
    }
}
转载自:https://juejin.cn/post/7133610412112773134
评论
请登录