RxAndroid组合Retrofit 实现文件上传 post get

RxAndroid组合Retrofit 实现文件上传 post get

   第一次写这种技术性的微博,请各位指点哈!RxAndroid和Retrofit都算是当下非常流行的Android开发框架,这两个框架光是单独使用就已经爽歪歪了,
   那么将RxAndroid和Retrofit结合起来,又会有怎样的效果呢?
  • **********第一次发博客 排版有点乱 我后期在处理哈 谢谢*************

1.RxJava优势
1.RxJava作为Android开发者的新宠已经有很长一段时间了,用过RxJava的人,都觉得这个东西简单好用,没用过的小伙伴第一次看到RxJava的代码时可能会觉得这个东西非常繁琐,总的,RxJava的优势就是“异步”处理的更好 比以前的asynctask(会出现内存泄露)。
RxJava的GitHub地址
2.给大家几个学习的参考教程吧 :
Android RxJava使用介绍 说的很详细,里面有四篇帖子哈.
深入浅出RxJava 这四篇帖子需要一点点的lambda语法哈 但是说的也很不错 ,推荐。

2.Retrofit的简单介绍

        Retrofit是Square公司开发的一款针对Android网络请求的框架,Retrofit2底层基于OkHttp实现的,OkHttp现在已经得到Google官方认可的网络请求。 

retrofit的github地址

3. RxAndroid+Retrofit(网络访问+文件上传)

需要添加的库
    compile 'io.reactivex:rxandroid:1.2.1'
    compile 'io.reactivex:rxjava:1.2.4'
    compile 'com.squareup.retrofit2:retrofit:2.1.0'
    compile 'com.alibaba:fastjson:1.1.55.android'
    compile 'com.squareup.retrofit2:converter-scalars:2.0.0-beta4'
    //打印网络日志的
    compile 'com.squareup.okhttp3:logging-interceptor:3.4.1'
    //retrofit2适应rxjava
    compile 'com.squareup.retrofit2:adapter-rxjava:2.1.0'

1.初始化OkHttpClient

     这里主要是初始化OkHttp客户端,配置一些基本分参数。
    private OkHttpClient getBaseOKhttpClient() {
        OkHttpClient.Builder builder = new OkHttpClient().newBuilder()
                .connectTimeout(20, TimeUnit.SECONDS)//设置超时时间
                .readTimeout(2000, TimeUnit.MILLISECONDS)//设置读取超时时间
                .writeTimeout(2000, TimeUnit.MILLISECONDS);//设置写入超时时间
        int cacheSize = 10 * 1024 * 1024; // 10 MiB//缓存大小,可酌情修改
        Cache cache = new Cache(BaseApplication.getInstance().getExternalCacheDir(), cacheSize);
        builder.cache(cache);//设置缓存目录
        builder.retryOnConnectionFailure(true);// 方法为设置出现错误进行重新连接。
        builder.addInterceptor(new HttpLoggingInterceptor().setLevel(HttpLoggingInterceptor.Level.BODY));//网络日志打印
        OkHttpClient mOkHttpClient = builder.build();//构建客户端
        return mOkHttpClient;

2.Retrofit的实体

   得到Retrofit的实体,处理配置基本信息
  private Retrofit getRetrofitInstance() {

        if (retrofit == null)
            //初始化Retrofit
            builder = new Retrofit.Builder();
        retrofit = builder
                .baseUrl(BASE_URL)//基本网址前缀,不可为空,或者是不配置.
                //增加retrofit对rxjava的支持   关联起来 必不可少的一步
                .addCallAdapterFactory(RxJavaCallAdapterFactory.create())
                //增加返回值为String的支持  我这里直接让他作为字符串返回就行了  
                // 可以添加其他的格式化工具,例如gson的 库 compile                                   //'com.squareup.retrofit2:converter-gson:2.1.0'  配置方法 
                //addConverterFactory(GsonConverterFactory.create()) 
                .addConverterFactory(ScalarsConverterFactory.create())
                .client(getBaseOKhttpClient())   //添加自定义的okhttp客户端
                .build();
        return retrofit;
    }

3.retrofit的请求类型:

    首先定义请求接口,即程序中都需要什么请求操作 POST  GET  Multipart(文件上传)
 interface HttpService {
        // 不然报错  @FieldMap parameters can only be used with form encoding. (parameter #2)
        @FormUrlEncoded
        @POST
        Observable<String> POST(@Url String url, @FieldMap Map<String, Object> parms);

        @GET
        Observable<String> GET(@Url String url, @QueryMap Map<String, Object> map);

        @Multipart
        @POST
        Observable<String> UploadMultFile(@Url String ulr, @PartMap Map<String, ProgressRequestBody> parms);
    }

4.执行网络请求

/**
     * 开始执行网络请求
     *
     * @param url        网址
     * @param parms      请求参数
     * @param subscriber 观察者
     */
    protected void startEnqueue(String url, Map parms, final Subscriber subscriber) {
        switch (callType) {
            case GET:
                request = ServiceType().GET(url, parms);
                break;
            case POST:
                request = ServiceType().POST(url, parms);
                break;
            case UPloadMultFile:
                Map requestBodys = new HashMap();
                Boolean hasFalse = false;
                if (null != parms) {
                    int i = 0;
                    for (Map.Entry entry : parms.entrySet()) {
                        File file = new File(entry.getValue() + "");
                        if (file.exists()) {
                            //requestBodys.put("file" + i + "\"; filename=\"" + file.getName(), RequestBody.create(MediaType.parse("image/png"), file));
                            logError(Uploadlistener + "");
                            ProgressRequestBody fileBody = new ProgressRequestBody(file, Uploadlistener);
                            requestBodys.put("file" + i + "\"; filename=\"" + file.getName(), fileBody);
                            i++;
                        } else {
                            hasFalse = true;
                        }
                    }
                }
                if (hasFalse) logError("部分文件目录异常,请稍后重试!");
                request = ServiceType().UploadMultFile(url, requestBodys);
                break;
        }
        // httpcallback.setRetryParms(url, request, parms, callType);
        subscriion = request.observeOn(AndroidSchedulers.mainThread())
                .subscribeOn(Schedulers.io())
                .subscribe(result -> {
                            //网络访问成功
                            Dto dto = JSON.parseObject(result.toString(), Dto.class);
                            if (!subscriber.isUnsubscribed())
                                subscriber.onNext(dto);
                        },
                        e -> {
                            //网络访问出错
                            subscriber.onError(e);
                        },
                        () -> {
                            //网络访问结束
                            subscriion.unsubscribe();//取消注册
                            subscriber.onCompleted();
                        }
                );
    }

5.请求方法的简单封装

   /**
     * post请求
     *
     * @param url
     * @param parms
     * @param subscriber 观察者
     */
    public void Post(@NonNull String url, @Nullable Map parms, @Nullable final Subscriber subscriber) {
        parms = Readey(parms, subscriber);
        callType = CallType.POST;
        startEnqueue(url, parms, subscriber);
    }

6.基本api的封装,方便添加一些基本信息和调用一些公用的方法


abstract class BaseApi {
    //    static {
//        System.loadLibrary("gongpan");
//    }
    protected static final String getUrl(String actition) {
        return actition + "?";
    }

    protected static final Map getMap() {
        Map maps = new HashMap();
        /**
         * temp:签名字段【app通过time和ieme通过native方法生成】
         ieme:设备号
         time:当前时间【生成方式:new Date().getTime()+""】
         */
        return maps;
    }
//xRetrofit是我写的一个网络请求的类  里面主要包括了 得到Retrofit的实体    初始化okhttp客户端,几种请求方法的基本封装 
/****
 * 懒汉模式
 */
public static xRetrofit init() {
    if (null == instance)
        synchronized (xRetrofit.class) {
            if (null == instance)
                instance = new xRetrofit();
        }
    return instance;
}
    protected static void post(String url, Map maps, Subscriber subscriber) {
        xRetrofit xretrofit = xRetrofit.init();//看上面代码  获取到xRetrofit这个类   方便调用里面的方法
        xretrofit.Post(url, maps, subscriber);//执行xRetrofit中公共post请求
    }

    protected static void get(String url, Map maps, Subscriber subscriber) {
        xRetrofit xretrofit = xRetrofit.init();
        xretrofit.GET(url, maps, subscriber);//执行xRetrofit中公共GET请求
    }

    protected static void UploadMultFile(String url, Map maps, ProgressRequestBody.UploadCallbacks Uploadlistener, Subscriber subscriber) {
        xRetrofit xretrofit = xRetrofit.init();
        xretrofit.UploadMultFile(url, maps, Uploadlistener, subscriber);
        //执行xRetrofit中公共UploadMultFile请求
    }
}

7.api的class写法:统一写,很方便调用,代码也很间接 继承baseapi:

//这里调用的是一个聚合数据的搞笑短语的集合    
public class HomeApi extends BaseApi {
    public static void getTopic_list(Subscriber subscriber) {
        String url = getUrl("joke/content/list.from");
        Map maps = getMap();
        maps.put("sort", "desc");
        maps.put("pagesize", "20");
        maps.put("time", "1418816972");
        maps.put("key", "df2e47d904c41e62071247bd7399da23");
        post(url, maps, subscriber);//执行的post请求
    }
    //文件上传的举例
    //Uploadlistener上传进度的监听

public static void FileUpload(List paths, ProgressRequestBody.UploadCallbacks Uploadlistener, Subscriber subscriber) {
String url = getUrlAppend(“app/AppFileUpload”);
Map


}

8.简单的封装了一下Subscriber,方便统一处理一下返回信息(错误处理,网络弹窗等等)


public abstract class BaseSubscriber extends Subscriber<Dto> {
    @Override
    public void onCompleted() {
        logError("请求结束");

    }

    @Override
    public void onError(Throwable t) {
        if (t.toString().contains("SocketTimeoutException")) {
            logError("亲,网络连接超时了,重试?");
            return;
        }
        if (t.toString().contains("ConnectException")) {
            logError("亲,无法连接到服务器,重试?");
            return;
        }

    }

    @Override
    public void onNext(Dto dto) {
    }

    public static void logError(Object obj) {
        Log.e("Xiang", obj.toString());
    }
}

9.在页面事件中api的调用,执行网络请求

//调用网络访问
HomeApi.getTopic_list(new BaseSubscriber() {
    @Override
    public void onNext(Dto dto) {
        super.onNext(dto);

    }
});

好了 ,先写到这里,空闲时间我会不断的完善。有啥bug欢迎各位前辈指出,谢谢

项目demo的github地址

你可能感兴趣的:(网络请求)