基于RxJava+Retrofit封装的网络框架

1.依赖库引入
implementation 'io.reactivex.rxjava2:rxjava:2.1.7'
implementation 'io.reactivex.rxjava2:rxandroid:2.0.1'
implementation 'com.squareup.retrofit2:retrofit:2.3.0'
implementation 'com.squareup.retrofit2:converter-gson:2.3.0'
implementation 'com.squareup.retrofit2:adapter-rxjava2:2.3.0'
implementation 'com.squareup.okhttp3:logging-interceptor:3.9.1'
2.基类设计
/**
 * 创建一个中间类用于建立M层和V层之间的连接,其实就是统一一个调用的入口,方便维护扩展
 */
public class Present<T extends BaseResult>{
    protected BaseObserver mObserver;
    public Present(BaseObserver observer) {
        mObserver = observer;
        //可根据mObserver的扩展属性进行相应的初始化管理
    }

    public void execute(Observable<T> observable) {
        if (mObserver.isLoading()) return;
        observable
                .subscribeOn(Schedulers.io())
                .unsubscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                //RxJava中map操作符也可以实现BaseObserver中对于接口规范中基础数据的处理,自行选择
                /**.map(new Function<BaseResult<T>, T>() {
                            @Override
                            public T apply(BaseResult<T> base){
                                return base.getResult();
                            }
                        })**/
                .subscribe(mObserver);
    }

    public static void execute(Observable observable, BaseObserver observer) {
        observable
                .subscribeOn(Schedulers.io())
                .unsubscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(observer);
    }
}

/**
 * 基础的观察者,类似传统BaseCallBack,处理接口规范的基层响应,该类应保持最基本的功能
 * 继承该类可扩展为与View层交互刷新页面,上传,列表刷新之类的Observer(ViewObserver)
 */
public abstract class BaseObserver<T extends BaseResult> implements Observer<T> {
    public enum Status {
        SUCCESS, NOT_DATA, FAILURE, NOT_LOGIN,
    }

    protected Disposable mDisposable;
    protected boolean isLoading;

    @Override
    public void onSubscribe(@NonNull Disposable d) {//类似onBefore(),可初始化菊花圈之类...
        Logger.i("onBefore");
        mDisposable = d;
    }

    @Override
    public void onNext(@NonNull T t) { //基础响应的处理,可根据后端业务调整,不与View耦合
        if(t==null){
           onError(new Throwable("系统异常"));
           return;
        }
        if(t.getCode()==0){
           onResponse(t,SUCCESS);
        }else if(t.getCode()==999){
           onResponse(t,NOT_LOGIN);
        }else{
           onResponse(t,FAILURE);
        }
    }

    protected abstract void onResponse(@NonNull T t, Status status);

    @Override
    public void onError(@NonNull Throwable e) {
        isLoading = false;
    }
    @Override
    public void onComplete() {
        isLoading = false;
    }
    public boolean isLoading() {
        return isLoading;
    }
}


/**
 * 基于与View层交互的Observer,将页面切换的操作统一封装在IViewSwitchImp类中
 * IViewSwitchImp代码可自行封装实现,此处只给出IViewSwitch 接口定义
 */
public abstract class ViewObserver<T> extends BaseObserver<BaseResult<T>> {
    protected IViewSwitch mIView;
    public ViewObserver(ViewGroup container) {
        mIView = new IViewSwitchImp(contentView);
    }
    public ViewObserver(IViewSwitch view) {
        mIView= view;
    }
    @Override
    public void onSubscribe(@NonNull Disposable d) {
        mIView.showLoading();
    }
    @Override
    protected void onResponse(BaseResult<T> result, Status status) {
        switch (status) {
            case SUCCESS:
                mIView.showContent();
                onSuccess(result.getResult());
                break;
            case NOT_DATA:
                mIView.showEmpty();
                break;
            case NOT_LOGIN:
                mIView.showLogin(t.getMessage());
                break;
            case FAILURE:
                mIView.showError(result.getMessage());
                break;
        }
    }

    public abstract void onSuccess(T t);

    @Override
    public void onError(@NonNull Throwable e) {
        Logger.d(e.getMessage());
        if (hasLoadDataSuccess) {
            Toaster.show(e.getMessage());
        } else {
            mSwitchViewHelper.showFailure(e);
        }
    }
}

public interface IViewSwitch{
    void showContent();
    void showEmpty();
    void showLoading();
    void showError(String msg);
}
3.Retrofit的封装
public class RetrofitFactory {

    private static final java.lang.Object Object = new Object();
    /**
     * 缓存机制
     * 在响应请求之后在 data/data/<包名>/cache 下建立一个response 文件夹,保持缓存数据。
     * 这样我们就可以在请求的时候,如果判断到没有网络,自动读取缓存的数据。
     * 同样这也可以实现,在我们没有网络的情况下,重新打开App可以浏览的之前显示过的内容。
     * 也就是:判断网络,有网络,则从网络获取,并保存到缓存中,无网络,则从缓存中获取。
     * https://werb.github.io/2016/07/29/%E4%BD%BF%E7%94%A8Retrofit2+OkHttp3%E5%AE%9E%E7%8E%B0%E7%BC%93%E5%AD%98%E5%A4%84%E7%90%86/
     */
    private static final Interceptor cacheControlInterceptor = new Interceptor() {

        @Override
        public Response intercept(Chain chain) throws IOException {
            Request request = chain.request();
            if (!NetWorkUtil.isNetworkConnected(MyApplication.AppContext)) {
                request = request.newBuilder().cacheControl(CacheControl.FORCE_CACHE).build();
            }

            Response originalResponse = chain.proceed(request);
            if (NetWorkUtil.isNetworkConnected(MyApplication.AppContext)) {
                // 有网络时 设置缓存为默认值
                String cacheControl = request.cacheControl().toString();
                return originalResponse.newBuilder()
                        .header("Cache-Control", cacheControl)
                        .removeHeader("Pragma")
                        .build();
            } else {
                // 无网络时 设置超时为1周
                int maxStale = 60 * 60 * 24 * 7;
                return originalResponse.newBuilder()
                        .header("Cache-Control", "public, only-if-cached, max-stale=" + maxStale)
                        .removeHeader("Pragma")
                        .build();
            }
        }
    };
    private volatile static Retrofit retrofit;

    @NonNull
    public static Retrofit getRetrofit() {
        synchronized (Object) {
            if (retrofit == null) {
                // 指定缓存路径,缓存大小 50Mb
                Cache cache = new Cache(new File(MyApplication.AppContext.getCacheDir(), "HttpCache"),
                        1024 * 1024 * 50);

//                // Cookie 持久化
//                ClearableCookieJar cookieJar =
//                        new PersistentCookieJar(new SetCookieCache(), new SharedPrefsCookiePersistor(InitApp.AppContext));

                OkHttpClient.Builder builder = new OkHttpClient.Builder()
//                        .cookieJar(cookieJar)
                        .cache(cache)
                        .addInterceptor(cacheControlInterceptor)
                        .connectTimeout(10, TimeUnit.SECONDS)
                        .readTimeout(15, TimeUnit.SECONDS)
                        .writeTimeout(15, TimeUnit.SECONDS)
                        .retryOnConnectionFailure(true);

                // Log 拦截器
                if (BuildConfig.DEBUG) {
                    builder = HttpBuilderWrapper.initInterceptor(builder);
                }

                retrofit = new Retrofit.Builder()
                        .baseUrl(ApiConstant.HOST)
                        .client(builder.build())
                        .addConverterFactory(GsonConverterFactory.create())
                        .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
                        .build();
            }
            return retrofit;
        }
    }
}

public interface IHomeApi {
    @FormUrlEncoded
    @POST("/goods/guessyoulikes/v2")
    Observable<BaseResult<HomeBean>> getContentList( @Field("userId")int userId);

}
4.调用
Observable<BaseResult<HomeBean>> observable = RetrofitFactory.getRetrofit().create(IHomeApi.class).getContentList(9527);

Present present = new Present(new ViewObserver<HomeBean>(new IViewSwitch()){
    @Override
    public void onSuccess(HomeBean bean){

    }
});
present.excute(observable);

Emmm… 写完发现并没有什么卵用,用Rxjava自带的链式调用似乎更简洁,这样做的好处在于,将网络的异常响应统一封装在一个可扩展的BaseObserver中并通过IViewSwitch展现给用户,仅此而已,做个记录

对于Android项目中的网络请求,RxJavaRetrofit和MVP是常用的框架组合。下面是一个简单的网络框架封装示例: 首先,在项目中引入RxJavaRetrofit的依赖。 ``` implementation 'io.reactivex.rxjava2:rxjava:2.2.19' implementation 'io.reactivex.rxjava2:rxandroid:2.1.1' implementation 'com.squareup.retrofit2:retrofit:2.9.0' implementation 'com.squareup.retrofit2:converter-gson:2.9.0' implementation 'com.squareup.retrofit2:adapter-rxjava2:2.9.0' ``` 然后,创建一个Retrofit的单例类,用于进行网络请求的初始化和配置。 ```java public class RetrofitClient { private static Retrofit retrofit; private static final String BASE_URL = "https://api.example.com/"; public static Retrofit getClient() { if (retrofit == null) { retrofit = new Retrofit.Builder() .baseUrl(BASE_URL) .addConverterFactory(GsonConverterFactory.create()) .addCallAdapterFactory(RxJava2CallAdapterFactory.create()) .build(); } return retrofit; } } ``` 接下来,创建一个ApiService接口,定义网络请求的方法。 ```java public interface ApiService { @GET("users") Observable<List<User>> getUsers(); } ``` 然后,创建一个DataManager类,用于管理网络请求。 ```java public class DataManager { private ApiService apiService; public DataManager() { apiService = RetrofitClient.getClient().create(ApiService.class); } public Observable<List<User>> getUsers() { return apiService.getUsers(); } } ``` 最后,在MVP的Presenter中调用DataManager类进行网络请求。 ```java public class UserPresenter { private UserView userView; private DataManager dataManager; public UserPresenter(UserView userView) { this.userView = userView; dataManager = new DataManager(); } public void getUsers() { dataManager.getUsers() .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .subscribe(new Observer<List<User>>() { @Override public void onSubscribe(Disposable d) { // 在请求开始时的操作 } @Override public void onNext(List<User> users) { // 请求成功返回数据时的操作 userView.showUsers(users); } @Override public void onError(Throwable e) { // 请求失败时的操作 userView.showError(e.getMessage()); } @Override public void onComplete() { // 请求完成时的操作 } }); } } ``` 这样,就完成了一个简单的Android RxJava + Retrofit + MVP网络框架封装。你可以根据自己的需要,进行进一步的封装和扩展。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值