Retrofit2+RxJava封装的网络框架(上)

在2016年7月份,有幸封装了Retrofit2+RxJava+Builder设计模式的网络框架。在今年去面试的过程中,被面试官提及Retrofit2和RxJava的知识,我竟有些答不出来,这令我非常难过。看来就算自己做过的东西也难免会忘的一干二净,这里呢,我将重新封装一下这个网络框架,并整理成博客,供大家相互学习,并加深一下自己的印象,避免不必要的尴尬。

我计划在今年(2018)年底将我的快速开发框架上传Github,到时候我会在这篇博文中贴出地址,望大家到时候支持一下哟。可能有人会问这么一个问题:都有那么多轮子了,你为什么还要造轮子呢?针对于这个问题我会针对于两个方向进行回答。

1.针对于公司,当然是用现成的轮子,因为项目当然是越快结项越好呀,自己造轮子耗时耗力。
2.针对于你自己,如果你想成长,就必须有造轮子的能力,这个快速开发框架是我闲的时候,工作之余搭建的,耗时两个月,期间既痛苦又快乐。
当完成的那一刻,向同事推荐出去,收到了赞赏和意见。都要虚心接受哟。这个封装好的网络框架就是其中之一。

废话不多说,大家现在看一下我封装的目录结构


解析:

1.bean目录 -- 用来参与解析的实体类
2.cookie目录 -- 主要用来持久化cookie的
3.gsonutil目录 -- GSON解析的封装,本来打算用大<T>解析的,
但是我一直未找到让GSON支持大<T>的解决办法,GSON只能处于解析实体类的地步。
所以就用了String解析。
4.loggingInterceptors目录 -- Log的封装,这是从网上下载的,是对HttpLoggingInterceptor的再次封装,友好的打印网络日志,序列化后缩进分明,展示清晰。
5.BaseRetrofitConfig -- 配置文件,包括baseUrl、追加公共参数等信息
6.BaseRetrofitFactory -- (1).配置OkHttpClient、添加拦截器 
    (2).添加HttpLoggingInterceptorM 日志拦截 (3).配置Retrofit
7.BaseRetrofitTwoService -- 网络请求接口Retrofit 2.+
8.NetModle -- 实现get post等方法,可在外部直接使用,极其方便。
9.NetSubscriber -- 可以在本类中对 Subscriber 获取到的数据进行处理。
10.OnNetSubscriberListener -- 自定义网络数据回调接口
11.tool目录 -- 工具类,包含LogUtil
12.Switch -- 有个方法控制是否打印Log,正式发布后关闭这个功能,其他功能不在介绍。

正文开始

第一步:创建快速开发框架(Moudle方式)

Moudle方式的好处是可随便移植,灵活性高,高效便捷。如果不懂的话请看我整理的另一篇博文,专门讲解Moudle的用法。《Android中Moudle的详细使用教程》

第二步:修改刚创建好的Moudle中的build.gradle文件

/* - 返回类型支持String - */
compile 'com.squareup.retrofit2:converter-scalars:2.0.0'//retrofit 框架   优化新增 +001

之上的代码,都是网络框架所用到的,包括这个,后面都有备注。我加的其他控件是快速开发框架里别的东西,你们做网络框架,只需要添加8个retrofit的依赖就行了,看备注后面有1/8r、2/8r的那8个

dependencies {
    compile 'com.android.support:appcompat-v7:25.3.1'
    compile fileTree(dir: 'libs', include: ['*.jar'])
    testCompile 'junit:junit:4.12'
    /* - (可选)okhttp3日志拦截器 调试使用,项目中存在自己封装的!!!,本包可不用 - */
//    compile 'com.squareup.okhttp3:logging-interceptor:3.4.1'//okhttp log拦截 版本必须和okhttp一致    1/8r

    /* - okhttp3 - */
    compile 'com.squareup.okhttp3:okhttp:3.4.1'//picasso + okHttp 2/2p  retrofit 框架  2/8r

    /* - retrofit2 - */
    compile 'com.squareup.retrofit2:retrofit:2.1.0'//retrofit 框架                         3/8r

    /* - gson - */
    compile 'com.google.code.gson:gson:2.7'//retrofit 框架                         4/8r

    /* - retrofit2使用gson需要添加这个包 - */
    compile 'com.squareup.retrofit2:converter-gson:2.1.0'//retrofit 框架                         5/8r

    /* - retrofit2使用rxjava需要添加这个包 - */
    compile 'com.squareup.retrofit2:adapter-rxjava:2.0.2'//retrofit 框架                         6/8r

    /* - 线程问题使用rxjava需要使用这个包 - */
    compile 'io.reactivex:rxandroid:1.1.0'//retrofit 框架                         7/8r

    /* - rxjava - */
    compile 'io.reactivex:rxjava:1.1.0'//retrofit 框架                         8/8r

    /* - 返回类型支持String - */
    compile 'com.squareup.retrofit2:converter-scalars:2.0.0'//retrofit 框架   优化新增 +001

    /* - 图片选择器 - */
//    compile 'com.lzy.widget:imagepicker:0.3.2'  //指定版本
    compile 'com.lzy.widget:imagepicker:0.5.5'  //指定版本
    compile 'com.github.nanchen2251:CompressHelper:1.0.5' //压缩配套使用

    /* - picasso - */
    compile 'com.squareup.picasso:picasso:2.5.2'//picasso + okHttp 1/2p

    /* - butterknife - */
    //临时没有有效方法可以让本控件支持library
//    compile 'com.jakewharton:butterknife:8.4.0'          //butterknife
//
//    apt 'com.jakewharton:butterknife-compiler:8.4.0'     //butterknife

    /* - 基于frame的新型下拉刷新控件 - */
    compile 'com.lcodecorex:tkrefreshlayout:1.0.5'


    //扫码思密达
    compile 'com.google.zxing:core:3.2.1'
    //扫码所需包
    compile 'pub.devrel:easypermissions:0.1.7'
    //权限
    compile 'cn.bingoogolapple:bga-qrcodecore:1.1.7@aar'
    //扫码所需包
    compile 'cn.bingoogolapple:bga-zxing:1.1.7@aar'

}

第三步:开始写代码

这篇文档我是分了上下两篇分开写的,上篇主要是讲的是重点代码,下篇讲的是辅助代码和用法。

重点代码只有这六个

5.BaseRetrofitConfig -- 配置文件,包括baseUrl、追加公共参数等信息
6.BaseRetrofitFactory -- (1).配置OkHttpClient、添加拦截器 
    (2).添加HttpLoggingInterceptorM 日志拦截 (3).配置Retrofit
7.BaseRetrofitTwoService -- 网络请求接口Retrofit 2.+
8.NetModle -- 实现get post等方法,可在外部直接使用,极其方便。
9.NetSubscriber -- 可以在本类中对 Subscriber 获取到的数据进行处理。
10.OnNetSubscriberListener -- 自定义网络数据回调接口

我将按顺序贴出代码,并讲解

这个是配置文件类,主要功能是设置参数,初始地址和超时时间等。初始化http的header响应头方便进行验签。

package com.abysskitty.frame.network;

import android.content.Context;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.util.ArrayMap;
import android.util.Log;

import com.abysskitty.frame.base.BaseApplication;
import com.abysskitty.frame.tool.DateUtil;
import com.abysskitty.frame.tool.EncryptUtil;

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

/**
 * Created by AbyssKitty on 2016/10/9.
 * Version 1.0
 * 配置文件,包括baseUrl、追加公共参数等信息
 */
public class BaseRetrofitConfig {

    /**
     * 总url路径 - 注意:Retrofit2.0 的baseUrl必须以“ / ”结尾,不然会抛出IllegalArgumentException异常
     * Retrofit2.0 支持全URL路径输入 所以在这里的路径就是个摆设,但却不能缺少
     * */
    public static final String baseUrl = "http://127.0.0.1:8080/api/v1/";

    /**
     * 连接超时时间,默认15s
     * */
    public static final int OKHTTP_OVERTIME = 15;


    /**
     * 需要追加的公共参数
     * Parame ->  未访问服务器之前,把此map拼接到上传的参数中
     * hander ->  开始访问服务器之前,把此map添加到hander响应头
     * */
    private static Map<String,String> Parame = new HashMap<>();
    private static Map<String,String> header = new HashMap<>();

    /**
     * 对 NetModle 开放获取公共参数的方法,此参数直接追加在parame中
     * 过时方法,已摒弃,需要在程序中动态添加
     * */
    @Deprecated
    public static Map getCommonParameter(){
        Parame.clear();
        Parame = new HashMap<>();
        //Parame.put("","");
        return Parame;
    }
    /**
     * 对 NetModle 开放获取公共参数方法,此方法追加在headers里
     * 过时方法,已摒弃,根据项目需求,-必须或者需要-在程序中动态添加
     * */
    @Deprecated
    public static Map getHanderCommonParameter() {
        header.clear();
//        header = getHeasers();
        header = new HashMap<>();
        //hander.put("","");
        return header;
    }

    private static String SoftVersion = "v1";//接口版本

    private static String AppKey = "4bafd51*********************23fe";

    private static String AppToken = "2e02b2***********************044";

    private static String SecretKey = "HON************************HOU";

    private static String Accept = "application/json";//接收的数据类型,如json、xml。

    private static String code = "055************************c56"; //动态的用户id

    private static String str = "";

    private static String str2 = "";

    private static String str3 = "";

    private static String str4 = "";

    public static Map<String,String> getHeasers(){
        Map<String,String> header = new HashMap<>();
        String AppVersion = BaseRetrofitConfig.getAppVersionName(BaseApplication.context);
        String AppName = BaseRetrofitConfig.getApplicationName(BaseApplication.context);
        try {
            str = EncryptUtil.base64Encoder(AppKey + ":" + AppToken + ":" + AppName + ":" + AppVersion + ":" + BaseRetrofitConfig.getTimestap());
            str2 = EncryptUtil.base64Encoder(SoftVersion);
            str3 = EncryptUtil.base64Encoder(code);
            str4 = EncryptUtil.createSignature(AppKey, AppToken, SecretKey);
        } catch (Exception e) {
            System.err.println("app验证错误!");
        }
        header.put("Accept", Accept);
        header.put("AppInfo", str);
        header.put("SoftVersion", str2);
        header.put("accountSid", str3);
        header.put("sig",str4);
        return header;
    }

    /**
     * 时间戳(只是服务器做记录)
     * @return
     */
    public static String getTimestap() {
        return DateUtil.format(new Date(), DateUtil.PIN_PATTERN_DATE_MINUTE);
    }

    /**
     * 返回当前版本名
     */
    public static String getAppVersionName(Context context) {
        String versionName = "";
        try {
            PackageManager pm = context.getPackageManager();
            PackageInfo pi = pm.getPackageInfo(context.getPackageName(), 0);
            versionName = pi.versionName;
            if (versionName == null || versionName.length() <= 0) {
                return "";
            }
        } catch (Exception e) {
            Log.e("VersionInfo", "Exception", e);
            e.printStackTrace();
        }
        return versionName;
    }

    /**
     * 获取当前应用名
     * @param context
     * @return
     */
    public static String getApplicationName(Context context) {
        PackageManager packageManager = null;
        ApplicationInfo applicationInfo = null;
        try {
            packageManager = context.getPackageManager();
            applicationInfo = packageManager.getApplicationInfo(context.getPackageName(), 0);
        } catch (PackageManager.NameNotFoundException e) {
            applicationInfo = null;
        }
        String applicationName =
                (String) packageManager.getApplicationLabel(applicationInfo);
        return applicationName;
    }
}

这个是重中之重,进行各种初始化,详情请见注释。通过builder模式初始化所用功能。

初始化retrofit,并加入日志拦截、缓存cookie、错误重连、超时时间、拦截添加header

并进行okhttp拦截。

package com.abysskitty.frame.network;

import com.abysskitty.frame.Switch;
import com.abysskitty.frame.base.BaseApplication;
import com.abysskitty.frame.network.cookie.CookieManger;
import com.abysskitty.frame.network.loggingInterceptors.okHttpLog.HttpLoggingInterceptorM;
import com.abysskitty.frame.network.loggingInterceptors.okHttpLog.LogInterceptor;

import java.io.IOException;
import java.net.SocketTimeoutException;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.TimeUnit;

import okhttp3.Interceptor;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
import retrofit2.Retrofit;
import retrofit2.adapter.rxjava.RxJavaCallAdapterFactory;
import retrofit2.converter.gson.GsonConverterFactory;
import retrofit2.converter.scalars.ScalarsConverterFactory;

/**
 * Created by AbyssKitty on 2016/10/9.
 * Version 1.0
 * 初始化Retrofit 2.+
 * 1.配置OkHttpClient、添加拦截器
 * 2.添加HttpLoggingInterceptorM 日志拦截
 * 3.配置Retrofit
 */
public class BaseRetrofitFactory {

    /**
     * 添加header响应头的集合,用于存放追加的header头的数据
     * */
    private Map<String,String> map = new HashMap<>();

    /**
     * 自定义Interceptor对象,用于在网络请求发出之前将header拦截添加进响应头
     * */
    private MyInterceptor myInterceptor = null;

    /**
     * 构造器,通过builder方式传入header响应头并初始化自定义拦截器Interceptor
     * */
    private BaseRetrofitFactory(Builder builder){
        map.clear();
        this.map = builder.map;
        myInterceptor = new MyInterceptor(map);
    }

    /**
     * okhttp的日志拦截,可在正式发布时关闭
     * */
//    private HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor().setLevel(HttpLoggingInterceptor.Level.BODY);
    /**
     * 自定义okhttp的日志拦截,可在正式发布时关闭
     * */
    private HttpLoggingInterceptorM interceptorM = new HttpLoggingInterceptorM(new LogInterceptor()).setLevel(HttpLoggingInterceptorM.Level.BODY);

    /**
     * 创建自定义OkHttpClient对象,初始化日志拦截、错误重连、超时、响应头等信息
     * */
    private OkHttpClient getClient(){
        OkHttpClient client = null;
        if(Switch.isDebug){
            client = new OkHttpClient.Builder()
                    .addInterceptor(interceptorM)                                           //日志拦截
                    .cookieJar(new CookieManger(BaseApplication.context))                   //缓存cookie
                    .retryOnConnectionFailure(true)                                         //错误重连
                    .connectTimeout(BaseRetrofitConfig.OKHTTP_OVERTIME, TimeUnit.SECONDS)   //超时时间
                    .addNetworkInterceptor(myInterceptor)                                   //拦截添加响应头
                    .build();
        }else{
            client = new OkHttpClient.Builder()
                    .cookieJar(new CookieManger(BaseApplication.context))                   //缓存cookie
                    .retryOnConnectionFailure(true)                                         //错误重连
                    .connectTimeout(BaseRetrofitConfig.OKHTTP_OVERTIME, TimeUnit.SECONDS)   //超时时间
                    .addNetworkInterceptor(myInterceptor)                                   //拦截添加响应头
                    .build();
        }
        return client;
    }

    /**
     * 初始化Retrofit对象,包括baseUrl、使用Gson解析、是用RxJava等。
     * */
    private Retrofit getRetrofit(){
        Retrofit retrofit = new Retrofit.Builder()
                .baseUrl(BaseRetrofitConfig.baseUrl)                                    //base地址
                .addConverterFactory(ScalarsConverterFactory.create())                  //添加解析方式为String
                .addConverterFactory(GsonConverterFactory.create())                     //添加解析方式为Gson
                .addCallAdapterFactory(RxJavaCallAdapterFactory.create())               //添加网络RxJava
                .client(getClient())                                                    //添加自定义OkHttpClient
                .build();
        return retrofit;
    }

    /**
     * 创建Retrofit实例
     * */
    public BaseRetrofitTwoService getRetrofitService(){

        BaseRetrofitTwoService service = getRetrofit().create(BaseRetrofitTwoService.class);

        return service;
    }

    /**
     * Builder
     * */
    public static class Builder{

        Map<String,String> map = new HashMap<>();

        public Builder setHeaders(Map<String,String> map){
            this.map = map;
            return this;
        }

        public BaseRetrofitFactory build(){
            return new BaseRetrofitFactory(this);
        }
    }

    /**
     * create by AbyssKitty on 2016/10/09.
     * Version 1.0
     * 每次ping 携带请求头 从OkHttp中拦截,Retrofit2只能使用注解方式添加headers
     * */
    public class MyInterceptor implements Interceptor {

        private Map<String, String> headers;

        public MyInterceptor(Map<String, String> headers) {
            this.headers = headers;
        }

        @Override
        public Response intercept(Chain chain) throws IOException {

            Response response = null;

            //同步 避免溢出
            synchronized (this){
                Request.Builder builder = chain.request()
                        .newBuilder();

                if (headers != null && headers.size() > 0) {

                    Set<String> keys = headers.keySet();

                    for (String headerKey : keys) {

                        builder.addHeader(headerKey, headers.get(headerKey)).build();

                    }

                    try{

                        response = chain.proceed(builder.build());

                    }catch (SocketTimeoutException e){
                        e.getLocalizedMessage();
                    }
                }else{

                    response = chain.proceed(builder.build());

                }
            }
//            获取error code 暂时不用
//            Response responseError = chain.proceed(chain.request());
//            responseError.code();
            return response;
        }

    }
}

把Retrofit的接口集合化使用,集合成一个接口,复用高效。

package com.abysskitty.frame.network;

import java.util.Map;

import okhttp3.MultipartBody;
import okhttp3.RequestBody;
import retrofit2.http.Body;
import retrofit2.http.FieldMap;
import retrofit2.http.FormUrlEncoded;
import retrofit2.http.GET;
import retrofit2.http.Multipart;
import retrofit2.http.POST;
import retrofit2.http.Part;
import retrofit2.http.PartMap;
import retrofit2.http.QueryMap;
import retrofit2.http.Streaming;
import retrofit2.http.Url;
import rx.Observable;

/**
 * Created by AbyssKitty on 2016/10/6.
 * Version 1.0
 * 网络请求接口Retrofit 2.+
 */
public interface BaseRetrofitTwoService {
    /**
     * create by AbyssKitty on 2016/10/06.
     * 以get方式的网络请求接口
     * @param url 可传全路径或者只传baseUrl之后的路径
     * @param map 键值对参数
     * */
    @GET("")
    Observable<String> get(@Url String url, @QueryMap Map<String, String> map);

    /**
     * create by AbyssKitty on 2016/10/06.
     * 以post方式的网络请求接口
     * @param url 可传全路径或者只传baseUrl之后的路径
     * @param map 键值对参数
     * */
    @POST("")
    Observable<String> post(@Url String url, @QueryMap Map<String, String> map);


    /**
     * post实体
     * */
    @POST("")
    Observable<String> postBody(@Url String url, @Body String body);

    /**
     * post表单
     * */
    @FormUrlEncoded
    @POST("")
    Observable<String> postField(@Url String url, @FieldMap Map<String, String> map);

    /**
     * 单图上传
     * */
    @Multipart
    @POST("")
    Observable<String> upLoadFile(
            @Url String url,
            @Part MultipartBody.Part file
    );

    /**
     * 测试中 多图上传
     * */
    @Multipart
    @POST("")
    Observable<String> uploadFiles(
            @Url String url,
            @Part("filename") String description,
            @PartMap() Map<String, RequestBody> maps);


    /**
     * 测试中 下载
     * */
    @Streaming
    @GET
    Observable<String> downloadFile(@Url String fileUrl);


}

自定义的Net操作类,简单化调用过程

package com.abysskitty.frame.network;

import com.abysskitty.frame.network.bean.RespBean;
import com.google.gson.Gson;

import java.io.File;
import java.util.HashMap;
import java.util.Map;

import okhttp3.MediaType;
import okhttp3.MultipartBody;
import okhttp3.RequestBody;
import rx.Subscriber;
import rx.android.schedulers.AndroidSchedulers;
import rx.schedulers.Schedulers;

/**
 * Created by AbyssKitty on 2016/10/11.
 * Version 1.0
 * Net 自定义封装
 * 实现get post等方法,可在外部直接使用。
 */
public class NetModle<T> {

    /* - resp里的list - */
    public final static int RESP_LIST = 0x560001;

    /* - resp里的obj - */
    public final static int RESP_OBJ = 0x560002;

    /* - resp里的info - */
    public final static int RESP_INFO = 0x560003;

    /* - list - */
    public final static int LIST = 0x560004;

    /* - obj - */
    public final static int OBJ = 0x560005;

    /* - info - */
    public final static int INFO = 0x560006;

    /**
     * 单例对象初始化,必须使用private修饰
     * */
    private NetModle(){}

    /**
     * 全局handers
     * */
    private Map<String,String> map = new HashMap<>();
    private Map<String,String> dmap = new HashMap<>();

    /**
     * Builder模式的初始化,保留
     * */
    private NetModle(Builder builder){
        this.map = builder.map;
    }

    /**
     * 获取单例
     * */
    public static NetModle getInstance(){
        return NetMoudleHolder.netModle;
    }

    /**
     * 静态内部类,实现线程安全、延迟加载、高效的单例模式。
     * */
    private static class NetMoudleHolder{
        private static NetModle netModle = new NetModle();
    }

    /**
     * get方式
     * @param url      地址
     * @param params   数据集合
     * @param onNetSubscriberListener    回调
     * */
    public void get(String url, Map<String,String> params , OnNetSubscriberListener onNetSubscriberListener){
        get(url,params,0,null,onNetSubscriberListener);
    }
    /**
     * @param url      地址
     * @param params   数据集合
     * @param type     返回的数据类型
     * @param onNetSubscriberListener    回调
     * */
    public void get(String url, Map<String,String> params, int type , OnNetSubscriberListener onNetSubscriberListener){
        get(url,params,type,null,onNetSubscriberListener);
    }
    /**
     * get方式
     * @param url      地址
     * @param params   数据集合
     * @param type     返回的数据类型
     * @param map      自定义的header集合
     * @param onNetSubscriberListener    回调
     * */
    public void get(String url, Map<String,String> params, int type, Map<String,String> map, OnNetSubscriberListener onNetSubscriberListener){
        //params = addParams(params);
        getBaseRetrofitFactory(map)
                .getRetrofitService()
                .get(url,params)
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(netNSListener(type,onNetSubscriberListener));
    }
    /**
     * post方式
     * @param url      地址
     * @param params   数据集合
     * @param onNetSubscriberListener    回调
     * */
    public void post(String url, Map<String,String> params , OnNetSubscriberListener onNetSubscriberListener){
        post(url,params,0,null,onNetSubscriberListener);
    }
    /**
     * post方式
     * @param url      地址
     * @param params   数据集合
     * @param type     返回的数据类型
     * @param onNetSubscriberListener    回调
     * */
    public void post(String url, Map<String,String> params, int type , OnNetSubscriberListener onNetSubscriberListener){
        post(url,params,type,null,onNetSubscriberListener);
    }
    /**
     * post方式
     * @param url   地址
     * @param params    数据集合
     * @param type     返回的数据类型
     * @param map   自定义的header集合,不传的话使用默认的header
     * @param onNetSubscriberListener    回调
     * */
    public void post(String url, Map<String,String> params, int type, Map<String,String> map, OnNetSubscriberListener onNetSubscriberListener){
        //params = addParams(params);
        getBaseRetrofitFactory(map)
                .getRetrofitService()
                .post(url,params)
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(netNSListener(type,onNetSubscriberListener));
    }

    /**
     * post传实体
     * */
    public void postBody(String url, String json, int type, Map<String,String> map, OnNetSubscriberListener onNetSubscriberListener){
//        RequestBody body = RequestBody.create(okhttp3.MediaType.parse("application/json"),json);
//        if(body != null){
//            LogUtil.d("-----------------------------1"+body.toString());
//
//        }else{
//            LogUtil.d("-----------------------------2");
//        }
        getBaseRetrofitFactory(map)
                .getRetrofitService()
                .postBody(url,json)
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(netNSListener(type,onNetSubscriberListener));

    }
    /**
     * post传表单FieldMap
     * */
    public void postField(String url, Map<String,String> parme, int type, Map<String,String> map, OnNetSubscriberListener onNetSubscriberListener){
        getBaseRetrofitFactory(map)
                .getRetrofitService()
                .postField(url,parme)
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(netNSListener(type,onNetSubscriberListener));
    }

    /**
     * 图片上传post方式
     * @param url   地址
     * @param path   图片地址
     * @param onNetSubscriberListener    回调
     * */
    public void upload(String url, String path, OnNetSubscriberListener onNetSubscriberListener){
        upload(url,path,0,null,onNetSubscriberListener);
    }

    /**
     * 图片上传post方式
     * @param url   地址
     * @param path   图片地址
     * @param type     返回的数据类型
     * @param map   自定义的header集合,不传的话使用默认的header
     * @param onNetSubscriberListener    回调
     * */
    public void upload(String url, String path, int type, Map<String,String> map, OnNetSubscriberListener onNetSubscriberListener){
        //Subscription d =
        getBaseRetrofitFactory(map)
                .getRetrofitService()
                .upLoadFile(url,getMultipartBodyPart(path))
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(netNSListener(type,onNetSubscriberListener));
    }
    /**
     * 图片上传post方式
     * @param url   地址
     * @param file   图片文件
     * @param type     返回的数据类型
     * @param map   自定义的header集合,不传的话使用默认的header
     * @param onNetSubscriberListener    回调
     * */
    public void upload(String url, File file, int type, Map<String,String> map, OnNetSubscriberListener onNetSubscriberListener){
        //Subscription d =
        getBaseRetrofitFactory(map)
                .getRetrofitService()
                .upLoadFile(url,getMultipartBodyPart(file))
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(netNSListener(type,onNetSubscriberListener));
    }
    /**
     * Subscriber 预处理
     * */
    private Subscriber netNSListener(final int type, final OnNetSubscriberListener onNetSubscriberListener){
        NetSubscriber<String> stringSubscriber = new NetSubscriber<String>() {
            @Override
            public void onCompleted() {
                super.onCompleted(); //执行预处理
//                if(onNetSubscriberListener != null){
//                    onNetSubscriberListener.onCompleted();
//                }
            }

            @Override
            public void onError(Throwable e){
                super.onError(e); //执行预处理
                if(onNetSubscriberListener != null){
                    onNetSubscriberListener.onError(e);
                }
            }

            @Override
            public void onNext(String s){
                super.onNext(s); //执行预处理
                Gson gson = new Gson();

                //去掉根节点 数据预处理,根据服务器数据修改!!!
                RespBean rb = gson.fromJson(s, RespBean.class);
//                    Object o = jsonGetObj(type,rb);
//                    if(onNetSubscriberListener != null){
//                        onNetSubscriberListener.onNext(rb,o);
                if(onNetSubscriberListener != null){
                    onNetSubscriberListener.onNext(rb);
                }
            }
        };
        return stringSubscriber;
    }
    /**
     * 初始数据预处理
     * */
    @Deprecated
    public Object jsonGetObj(int type, RespBean rb){
        Object o = null;
        Gson gson = new Gson();
        switch (type){
            case RESP_LIST:
                o = rb.resp.list;
                break;
            case RESP_INFO:
                o = gson.toJson(rb.resp.info);
                break;
            case RESP_OBJ:
                o = gson.toJson(rb.resp.obj);
                break;
            case LIST:
                o = rb.list;
                break;
            case INFO:
                o = gson.toJson(rb.info);
                break;
            case OBJ:
                o = gson.toJson(rb.obj);
                break;
            default:
        }
        return o;
    }
    /**
     * 文件上传
     * */
    private MultipartBody.Part getMultipartBodyPart(String mPath){
        File file = new File(mPath);
        //multipart/form-data 格式
        RequestBody requestFile =
                RequestBody.create(MediaType.parse("multipart/form-data"), file);
        //file - 为上传参数的 键名
        MultipartBody.Part body =
                MultipartBody.Part.createFormData("file", file.getName(), requestFile);
        return body;
    }
    /**
     * 文件上传
     * */
    private MultipartBody.Part getMultipartBodyPart(File file){
        //multipart/form-data 格式
        RequestBody requestFile =
                RequestBody.create(MediaType.parse("multipart/form-data"), file);
        //file - 为上传参数的 键名
        MultipartBody.Part body =
                MultipartBody.Part.createFormData("file", file.getName(), requestFile);
        return body;
    }

    /**
     * 获取RetrofitFactory对象
     * */
    private BaseRetrofitFactory getBaseRetrofitFactory(Map<String,String> map){

        BaseRetrofitFactory baseRetrofitFactory = null;

        if(map != null){

            baseRetrofitFactory = new BaseRetrofitFactory.Builder()
                    .setHeaders(map)
                    .build();
        }else{
            /* 在这里添加默认的 handers */
            dmap = BaseRetrofitConfig.getHanderCommonParameter();
            //LogUtil.d("getHanderCommonParameter="+dmap.size()+" moren");
            baseRetrofitFactory = new BaseRetrofitFactory.Builder()
                    .setHeaders(dmap)
                    .build();
        }
        return baseRetrofitFactory;
    }

    /**
     * 追加params数据
     * 可不用此方法,已摒弃
     * */
    @Deprecated
    private Map addParams(Map parame){
        Map<String,String> p = null;
        p = BaseRetrofitConfig.getCommonParameter();
        if(p != null){
            parame.putAll(p);
        }
        return parame;
    }

    /**
     * Builder,留用 暂时未用 ,当前是以静态方法方式实现的
     * */
    public class Builder{

        Map<String,String> map;

        Map<String,String> params;

        public Builder setHander(Map<String,String> map){
            this.map = map;
            return this;
        }

        public Builder setMap(Map<String,String> params){
            this.params = params;
            return this;
        }

        public NetModle build(){
            return new NetModle(this);
        }
    }
}

这是CSDN的源码下载链接:https://download.csdn.net/download/sinat_30949835/10314758

这是CSDN的下载连接:https://download.csdn.net/download/sinat_30949835/10299497


  • 2
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值