retrofit+mvp+okhttp+rxjava封装

首先是retrofit和okhttp的封装:

因为retrofit的底层就是用okhttp请求网络的,所以可以通过就是设置okhttp的连接超时,缓存,日志等,将它加入到retrofit中。

具体代码:

import android.content.Context;
import android.util.Log;

import com.jakewharton.retrofit2.adapter.rxjava2.RxJava2CallAdapterFactory;
import com.seehealth.easynet.http.RetrofitService;
import com.seehealth.easynet.http.ServiceConfig;

//import org.simpleframework.xml.Serializer;
//import org.simpleframework.xml.convert.AnnotationStrategy;
//import org.simpleframework.xml.core.Persister;
//import org.simpleframework.xml.strategy.Strategy;

import java.io.File;
import java.util.concurrent.TimeUnit;

import okhttp3.Cache;
import okhttp3.Interceptor;
import okhttp3.OkHttpClient;
import okhttp3.logging.HttpLoggingInterceptor;
import retrofit2.Retrofit;
import retrofit2.converter.gson.GsonConverterFactory;
import retrofit2.converter.scalars.ScalarsConverterFactory;
//import retrofit2.converter.simplexml.SimpleXmlConverterFactory;

/**
 * Created by ljj on 2017/9/29.
 */

public class RetrofitManager {

    private volatile static RetrofitManager retrofitManager;
    private RetrofitService retrofitService;

//    private static Strategy strategy = new AnnotationStrategy();
//    private static Serializer serializer = new Persister(strategy);

    private RetrofitManager(Context context) {
        OkHttpClient okHttpClient = initOkHttpClient(context);
        Retrofit retrofit = initRetrofit(okHttpClient);
        retrofitService = retrofit.create(RetrofitService.class);
    }

    public static RetrofitManager getInstance(Context context) {
        if (retrofitManager == null) {
            synchronized (RetrofitManager.class) {
                if (retrofitManager == null) {
                    retrofitManager = new RetrofitManager(context);
                }
            }
        }
        return retrofitManager;
    }

    public RetrofitService getRetrofitService() {
        return retrofitService;
    }

    /**
     * 初始化okhttp
     *
     * @param context
     * @return
     */
    private OkHttpClient initOkHttpClient(Context context) {
        //新建一个文件用来缓存网络请求
        File cacheDirectory = new File(context.getCacheDir().getAbsolutePath() + "responses");
        OkHttpClient okHttpClient = new OkHttpClient.Builder()
                .connectTimeout(ServiceConfig.TIMEOUT, TimeUnit.SECONDS)//设置连接超时
                .readTimeout(ServiceConfig.TIMEOUT, TimeUnit.SECONDS)//设置从主机读信息超时
                .writeTimeout(ServiceConfig.TIMEOUT, TimeUnit.SECONDS)//设置写信息超时
                .retryOnConnectionFailure(true)///如果连接失败,尝试重连
                .cache(new Cache(cacheDirectory, 10 * 1024 * 1024))//设置缓存文件
                .addInterceptor(initInterceptor())//设置okhttp拦截器,这样做的好处是可以为你的每一个retrofit2的网络请求都增加相同的head头信息,而不用每一个请求都写头信息
                .addInterceptor(initLogInterceptor())//打印日志
                .build();
        return okHttpClient;
    }

    /**
     * 初始化http拦截器
     *
     * @return
     */
    private Interceptor initInterceptor() {
        BasicParamsInterceptor builder = new BasicParamsInterceptor.Builder()
//                .addHeaderParam("Content-Type", "text/xml; charset=utf-8")// 对于SOAP 1.1, 如果是soap1.2 应是Content-Type: application/soap+xml; charset=utf-8
                .build();
        return builder;
    }

    /**
     * 初始化日志信息
     *
     * @return
     */
    private Interceptor initLogInterceptor() {
        HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor(new HttpLoggingInterceptor.Logger() {
            @Override
            public void log(String message) {
                Log.i("TTT", "请求参数:" + message);
            }
        });
        interceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
        return interceptor;
    }

    /***
     * 初始化Retrofit
     */
    private Retrofit initRetrofit(OkHttpClient client) {
        Retrofit retrofit = new Retrofit.Builder()
                .client(client)//设置 HTTP Client  用于请求的连接
//                .addConverterFactory(SimpleXmlConverterFactory.create(serializer))//解析xml
                .addConverterFactory(ScalarsConverterFactory.create())//如果网络访问返回的字符串,而不是json数据格式,要使用下面的转换器
                .addConverterFactory(GsonConverterFactory.create())//如果网络访问返回的是json字符串,使用gson转换器
                .addCallAdapterFactory(RxJava2CallAdapterFactory.create())//此处顺序不能和上面对调,否则不能同时兼容普通字符串和Json格式字符串  为了支持rxjava,需要添加下面这个把 Retrofit 转成RxJava可用的适配类
                .baseUrl(ServiceConfig.BASE_URL)
                .build();
        return retrofit;
    }

}

接着是初步封装mvp层,已登入为例子:

我的目录结构,一个model对应一个presenter对应多个view

因为presenter都会接收到model返回来的结果,所以我将它单独写成了一个父类IPresenter:

public interface IPresenter {
    void success(int code, Object result);

    void error(int code, String result);
}

每个Presenter接口类都继承IPresenter:

public interface IAccountPresenter extends IPresenter {
    /**
     * 登入
     *
     * @param userName
     * @param password
     */
    void login(String userName, String password); }

一般写法是

 rService.login(userName, password)
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Subscriber<Object>() {
                    @Override
                    public void onSubscribe(Subscription s) {
                        
                    }

                    @Override
                    public void onNext(Object o) {

                    }

                    @Override
                    public void onError(Throwable t) {

                    }

                    @Override
                    public void onComplete() {

                    }
                });

封装后写法:

 rService.login(userName, password)
                .compose(new RxFlowableTransformer())
                .subscribe(new IRxSubscribler(basePresenter, HttpInterfaceCode.LOGIN_SUC));

我的model实现类:

/**
 * 用户具体实现类
 * Created by 1 on 2018/1/24.
 */

public class AccountModelImpl implements IAccountModel {
    private RetrofitService rService;
    private IPresenter basePresenter;

    public AccountModelImpl(RetrofitManager retrofitManager, IPresenter basePresenter) {
        rService = retrofitManager.getRetrofitService();
        this.basePresenter = basePresenter;
    }

    @Override
    public void login(String userName, String password) {
        rService.login(userName, password)
                .compose(new RxFlowableTransformer())
                .subscribe(new IRxSubscribler(basePresenter, HttpInterfaceCode.LOGIN_SUC));
    }

    @Override
    public void register(AccountBean account) {
        rService.register(account)
                .compose(new RxFlowableTransformer())
                .subscribe(new IRxSubscribler(basePresenter, HttpInterfaceCode.REGISTER_SUC));
    }

    @Override
    public void forgetPassword(AccountBean accountBean) {
        rService.forgetPw(accountBean)
                .compose(new RxFlowableTransformer())
                .subscribe(new IRxSubscribler(basePresenter, HttpInterfaceCode.FORGET_PW_SUC));
    }
}

因为我将Ipresenter放到了 model类中,所以结果直接回调到了presenter的实现类中success和error方法中;

RxFlowableTransformer类很简单,就是封装了线程而已:

public final class RxFlowableTransformer implements FlowableTransformer {
    @Override
    public Publisher apply(Flowable upstream) {
        return upstream.subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread());
    }

}

接着看IRxSubscribler类,有两个参数,一个是iPresenter引用,还有一个是接口回调成功值(如值为20,则接口回调失败会返回-20);

public class IRxSubscribler<T> extends RxSubscribler<T> {
    private IPresenter basePresenter;
    private int interfaceCode;

    public IRxSubscribler(IPresenter basePresenter, int interfaceCode) {
        this.basePresenter = basePresenter;
        this.interfaceCode = interfaceCode;
    }

    @Override
    public void success(Object o) {
        basePresenter.success(interfaceCode, o);
    }

    @Override
    public void error(String result) {
        basePresenter.error(-interfaceCode, result);
    }
}

这里只是进行了回调操作,接着去RxSubscribler类

public abstract class RxSubscribler<T> implements Subscriber<T> {
    @Override
    public final void onSubscribe(Subscription s) {
        s.request(Long.MAX_VALUE);
    }

    @Override
    public final void onNext(T o) {
        checkIsSucc(o);
    }

    @Override
    public final void onError(Throwable t) {

        if (t instanceof SocketTimeoutException) {
            error("服务器连接超时");
        } else if (t instanceof ConnectException) {
            error("服务器链接失败");
        } else if (t instanceof TimeoutException) {
            error("网络超时");
        } else if (t instanceof UnknownHostException) {
            error("未知主机错误");
        } else {
            error("未知错误");
            t.printStackTrace();
        }
    }

    @Override
    public final void onComplete() {

    }

    public abstract void success(T o);

    public abstract void error(String result);

    private void checkIsSucc(T o) {
        if (o instanceof BaseResponse) {
            BaseResponse response = (BaseResponse) o;
            String errorMessage = "未知错误";
            switch (response.getCode()) {
                case HttpInterfaceCode.NET_REUQEST_OK:
                    success(o);
                    return;
                case HttpInterfaceCode.NET_REQUEST_ERROR:
                    errorMessage = "请求错误";
                    break;
                case HttpInterfaceCode.NET_REQUEST_REJECT:
                    errorMessage = "请求被拒绝";
                    break;
                case HttpInterfaceCode.NET_REQUEST_UNFOUND:
                    errorMessage = "请求未响应";
                    break;
                case HttpInterfaceCode.NET_SERVICE_ERROR:
                    errorMessage = "服务器错误";
                    break;
                case HttpInterfaceCode.NET_NUKNOWN_ERROR:
                    errorMessage = "未知错误";
                    break;
            }
            error(errorMessage);
        }

    }
}

流程大概就是这样。源码会在以后发布到github上

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值