美文网首页Android架构AndroidAndroid开发
Android Rxjava+Retrofit网络请求框架封装(

Android Rxjava+Retrofit网络请求框架封装(

作者: 斌林诚上 | 来源:发表于2019-03-01 23:46 被阅读83次
    image

    目录

    一、简介
    二、Retrofit基本使用
    (1)在build文件中加入相关依赖
    (2)基本使用
    (3)测试
    三、Retrofit 自定义的OkHttpClient
    (1)设置自定义的OkHttpClient
    (2)Retrofit 添加client
    (3)打印效果
    四、Retrofit 与 Rxjava 结合使用
    (1)添加依赖
    (2)Retrofit 设置
    (3)其他修改
    (4)测试结果
    五、防止Rxjava引发的内存泄漏
    (1)添加依赖
    (2)基本使用
    六、总结与封装
    七、Demo地址
    八、内容推荐


    前言

    这是第二次改编、之前第一次写这篇博客的时候只是当成笔记记录一下。都没有怎么仔细介绍内容,可能导致一些朋友们没看明白,这次重新组织一下。当然由于内容比较多,不可能太详细。我尽量做到让更多人能够看明白,哈哈 当然 朋友们也要跟着我的步骤一步一步来实现 ,这样会比较好理解。

    一、简介

    大家都知道Retrofit是对OKHttp的第二次封装,使用上也比较简单。那为什么还要对Retrofit进行封装呢,个人理解主要还是对Retrofit进行更规范的分类,有利于项目的开发与维护,提高网络请求这一块的效率。好了,可以开始跟我走了。。一步一步的走向巅峰,然后再回头来听我吹牛逼。。

    ​​​​ 2.gif

    二、Retrofit基本使用

    (1)在build文件中加入相关依赖

    //github地址:https://github.com/square/retrofit
    //文档地址:https://square.github.io/retrofit/
    implementation 'com.squareup.retrofit2:retrofit:2.5.0'
    
    image.gif

    (2)基本使用

    public interface ApiUrl {
        //get请求
        @GET(Constans.retrofit)
        Call<Bean> getRetrofit();
    }
    
    
    image.gif
    Retrofit retrofit = new Retrofit.Builder()
                    .baseUrl(Constans.BaseUrl)
                    .build();
    
            ApiUrl api = retrofit.create(ApiUrl.class);
            Call<Bean> demo = api.getRetrofit();
            demo.enqueue(new Callback<Bean>() {
                @Override
                public void onResponse(Call<Bean> call, Response<Bean> response) {
                    Log.e(TAG, "请求成功信息: "+response.body().toString());
                }
    
                @Override
                public void onFailure(Call<Bean> call, Throwable t) {
                    Log.e(TAG, "请求失败信息: " +t.getMessage());
                }
            });
    
    image.gif

    目前大部分后台一般会返回JSON数据类型所以我们需要Retrofit 添加JSON支持

        //retrofit添加Json解析返回数据
        implementation 'com.squareup.retrofit2:converter-gson:2.5.0'
    
    image.gif
            Retrofit retrofit = new Retrofit.Builder()
                    .baseUrl(Constans.BaseUrl)
                    //添加GSON解析:返回数据转换成GSON类型 
                    .addConverterFactory(GsonConverterFactory.create())
                    .build();
    
    image.gif

    这样就可以解析JSON数据

    (3)测试

    这里提供测试Url,返回的是JSON数据类型

        public final static  String BaseUrl = "http://pndatsn5v.bkt.clouddn.com/";
        public final static  String retrofit = "retrofit.txt";
    
    image.gif

    映射返回数据

    /**
     * {
     *     "res_code": 200,
     *     "err_msg": "Web page does not exist",
     *     "demo": {
     *         "id": "1001",
     *         "appid": "1021",
     *         "name": "sss",
     *         "showtype": "text"
     *     }
     * }
     */
    public class Bean {
    
        @Override
        public String toString() {
            return "bean{" +
                    "res_code=" + res_code +
                    ", err_code=" + err_code +
                    ", err_msg='" + err_msg + '\'' +
                    ", demo=" + demo +
                    '}';
        }
        private int res_code;
        private int err_code;
        private String err_msg;
        private DemoBean demo;
    
        public int getRes_code() {
            return res_code;
        }
    
        public void setRes_code(int res_code) {
            this.res_code = res_code;
        }
    
        public int getErr_code() {
            return err_code;
        }
    
        public void setErr_code(int err_code) {
            this.err_code = err_code;
        }
    
        public String getErr_msg() {
            return err_msg;
        }
    
        public void setErr_msg(String err_msg) {
            this.err_msg = err_msg;
        }
    
        public DemoBean getDemo() {
            return demo;
        }
    
        public void setDemo(DemoBean demo) {
            this.demo = demo;
        }
    
        public static class DemoBean {
            @Override
            public String toString() {
                return "DemoBean{" +
                        "id='" + id + '\'' +
                        ", appid='" + appid + '\'' +
                        ", name='" + name + '\'' +
                        ", showtype='" + showtype + '\'' +
                        '}';
            }
            private String id;
            private String appid;
            private String name;
            private String showtype;
    
            public String getId() {
                return id;
            }
    
            public void setId(String id) {
                this.id = id;
            }
    
            public String getAppid() {
                return appid;
            }
    
            public void setAppid(String appid) {
                this.appid = appid;
            }
    
            public String getName() {
                return name;
            }
    
            public void setName(String name) {
                this.name = name;
            }
    
            public String getShowtype() {
                return showtype;
            }
    
            public void setShowtype(String showtype) {
                this.showtype = showtype;
            }
        }
    }
    
    image.gif

    发送请求并打印返回数据

     Retrofit retrofit = new Retrofit.Builder()
                    .baseUrl(Constans.BaseUrl)
                    //添加GSON解析
                    .addConverterFactory(GsonConverterFactory.create())
                    .build();
    
            ApiUrl api = retrofit.create(ApiUrl.class);
            Call<Bean> demo = api.getRetrofit();
            demo.enqueue(new Callback<Bean>() {
                @Override
                public void onResponse(Call<Bean> call, Response<Bean> response) {
                    Log.e(TAG, "请求成功信息: "+response.body().toString());
                }
    
                @Override
                public void onFailure(Call<Bean> call, Throwable t) {
                    Log.e(TAG, "请求失败信息: " +t.getMessage());
                }
            });
    
    image.gif

    别忘了——添加网络权限

        <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
        <uses-permission android:name="android.permission.INTERNET"/>
    
    image.gif

    打印结果:

     E/RetrofitActivity: 请求成功信息: bean{res_code=200, err_code=0, err_msg='Web page does not exist', demo=DemoBean{id='1001', appid='1021', name='sss', showtype='text'}}
    
    image.gif

    三、Retrofit 自定义的OkHttpClient

    这里介绍一些常用的设置

    (1)设置自定义的OkHttpClient

           OkHttpClient client = new OkHttpClient().newBuilder()
                    .readTimeout(Constans.DEFAULT_TIME, TimeUnit.SECONDS)//设置读取超时时间
                    .connectTimeout(Constans.DEFAULT_TIME, TimeUnit.SECONDS)//设置请求超时时间
                    .writeTimeout(Constans.DEFAULT_TIME,TimeUnit.SECONDS)//设置写入超时时间
                    .addInterceptor(new LogInterceptor())//添加打印拦截器
                    .retryOnConnectionFailure(true)//设置出现错误进行重新连接。
                    .build();
    
    image.gif
        //设置默认超时时间
        public static final int DEFAULT_TIME=10;
    
    image.gif
    /**
     *  TODO Log拦截器代码
     */
    public class LogInterceptor implements Interceptor{
        private String TAG = "okhttp";
    
        @Override
        public okhttp3.Response intercept(Chain chain) throws IOException {
            Request request = chain.request();
            Log.e(TAG,"request:" + request.toString());
            long t1 = System.nanoTime();
            okhttp3.Response response = chain.proceed(chain.request());
            long t2 = System.nanoTime();
            Log.e(TAG,String.format(Locale.getDefault(), "Received response for %s in %.1fms%n%s",
                    response.request().url(), (t2 - t1) / 1e6d, response.headers()));
            okhttp3.MediaType mediaType = response.body().contentType();
            String content = response.body().string();
            Log.e(TAG, "response body:" + content);
            return response.newBuilder()
                    .body(okhttp3.ResponseBody.create(mediaType, content))
                    .build();
        }
    }
    
    image.gif

    (2)Retrofit 添加client

            Retrofit retrofit = new Retrofit.Builder()
                    //设置自定义okHttp
                    .client(client)
                    .baseUrl(Constans.BaseUrl)
                    //添加GSON解析
                    .addConverterFactory(GsonConverterFactory.create())
                    .build();
    
    image.gif

    (3)打印效果

    E/okhttp: request:Request{method=GET, url=http://pndatsn5v.bkt.clouddn.com/retrofit.txt, tags={class retrofit2.Invocation=retrofit.interfaces.ApiUrl.getRetrofit() []}}
    
    E/okhttp: Received response for http://pndatsn5v.bkt.clouddn.com/retrofit.txt in 55.1ms
        Server: Tengine
        Content-Type: text/plain
        Connection: keep-alive
        Date: Sat, 23 Feb 2019 08:17:35 GMT
        Accept-Ranges: bytes
        Access-Control-Allow-Origin: *
        Access-Control-Expose-Headers: X-Log, X-Reqid
        Access-Control-Max-Age: 2592000
        Cache-Control: public, max-age=31536000
        Content-Disposition: inline; filename="retrofit.txt"; filename*=utf-8' 'retrofit.txt
        Content-Transfer-Encoding: binary
        Etag: "Fh65gSkYd4KepQbHi-rWZDlhKjmO.gz"
        Last-Modified: Sat, 23 Feb 2019 08:14:42 GMT
        Vary: Accept-Encoding
        X-Log: AC;CFGG:4;redis.g/404;redis.g;rs5_shard.sel:2;rwro.get:2;RS.dbs:2;RS:3;redis.s;2s.gh;PFDS;AUTHPROXY_dg_out;IO:85
        X-M-Log: QNM:xs1172;QNM3
        X-M-Reqid: dGUAAMyobctL8IUV
        X-Qiniu-Zone: 2
        X-Qnm-Cache: Hit
        X-Reqid: EkMAAA7s1xso8IUV
        X-Svr: IO
        Ali-Swift-Global-Savetime: 1550909855
        Via: cache4.l2et15[10,200-0,M], cache15.l2et15[11,0], vcache19.cn1177[0,200-0,H], vcache2.cn1177[1,0]
        Age: 80679
        X-Cache: HIT TCP_MEM_HIT dirn:2:55209266
        X-Swift-SaveTime: Sat, 23 Feb 2019 08:17:35 GMT
        X-Swift-CacheTime: 2592000
        Timing-Allow-Origin: *
        EagleId: 1b9f47ca15509905340914033e
    
    E/okhttp: response body:{
            "res_code": 200,
            "err_msg": "Web page does not exist",
            "demo": {
                "id": "1001",
                "appid": "1021",
                "name": "sss",
                "showtype": "text"
            }
        }
    
    E/RetrofitActivity: 请求成功信息: bean{res_code=200, err_code=0, err_msg='Web page does not exist', demo=DemoBean{id='1001', appid='1021', name='sss', showtype='text'}}
    
    
    image.gif

    四、Retrofit 与 Rxjava 结合使用

    (1)添加依赖

    implementation 'com.jakewharton.retrofit:retrofit2-rxjava2-adapter:1.0.0'
    
    image.gif

    (2)Retrofit 设置

    Retrofit retrofit = new Retrofit.Builder()
                    .client(client)
                    .baseUrl(Constans.BaseUrl)
                    //添加GSON解析:返回数据转换成GSON类型
                    .addConverterFactory(GsonConverterFactory.create())
                    //添加Rxjava支持
                    .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
                    .build();
    
    image.gif

    (3)其他修改

    //@GET(Constans.retrofit)
    //Call<Bean> getRetrofit();
    
    @GET(Constans.retrofit)
    Observable<Bean> getRetrofit1();
    
    image.gif
            retrofit.create(ApiUrl.class)
                    .getRetrofit1()
                    .subscribeOn(Schedulers.io())
                    .observeOn(AndroidSchedulers.mainThread())
                    .subscribe(new Observer<Bean>() {
                        @Override
                        public void onSubscribe(Disposable d) {
                            Log.e(TAG, "onSubscribe: " );
                        }
    
                        @Override
                        public void onNext(Bean demo) {
                            Log.e(TAG, "onNext: " +demo.toString());
                        }
    
                        @Override
                        public void onError(Throwable e) {
                            Log.e(TAG, "Throwable: " + e.getMessage());
                        }
    
                        @Override
                        public void onComplete() {
                            Log.e(TAG, "onComplete: " );
                        }
                    });
    
    image.gif

    (4)测试结果

    E/RetrofitActivity: onSubscribe: 
    E/RetrofitActivity: onNext: bean{res_code=200, err_code=0, err_msg='Web page does not exist', demo=DemoBean{id='1001', appid='1021', name='sss', showtype='text'}}
    E/RetrofitActivity: onComplete: 
    
    image.gif

    五、防止Rxjava引发的内存泄漏

    当使用RxJava订阅并执行耗时任务后,当Activityfinish时,如果耗时任务还未完成,没有及时取消订阅,就会导致Activity无法被回收,从而引发内存泄漏。为了解决这个问题,就产生了RxLifecycle,让RxJava变得有生命周期感知,使得其能及时取消订阅,避免出现内存泄漏问题。

    (1)添加依赖

        implementation 'com.trello.rxlifecycle2:rxlifecycle-components:2.1.0'
    
    image.gif

    (2)基本使用

    Activity 需继承自 RxAppCompatActivity 或 RxFragmentActivity 或 RxActivity

    Fragment 需继承 RxFragment

    retrofit.create(ApiUrl.class)
                    .getRetrofit1()
                    .subscribeOn(Schedulers.io())
                    .observeOn(AndroidSchedulers.mainThread())
                    //绑定生命周期
                    .compose(bindUntilEvent(ActivityEvent.DESTROY))
                    .subscribe(new Observer<Bean>() {
                        @Override
                        public void onSubscribe(Disposable d) {
                            Log.e(TAG, "onSubscribe: " );
                        }
    
                        @Override
                        public void onNext(Bean demo) {
                            Log.e(TAG, "onNext: " +demo.toString());
                        }
    
                        @Override
                        public void onError(Throwable e) {
                            Log.e(TAG, "Throwable: " + e.getMessage());
                        }
    
                        @Override
                        public void onComplete() {
                            Log.e(TAG, "onComplete: " );
                        }
                    });
    
    image.gif

    好了 目前了解这些已经够用了 不过直接使用还是很麻烦,重复代码比较多 。所以需要进行整理和封装

    image

    六、总结与封装

    《Android Rxjava+Retrofit网络请求框架封装(二)》

    七、Demo地址

    https://github.com/DayorNight/RxjavaRetrofit2

    八、内容推荐

    CSDN:
    《Android Rxjava+Retrofit网络请求框架封装(一)》

    《Android JUnit单元测试》

    《Android Log日志封装》

    《Android 仿微信全局字体大小调整》

    如果你觉得我写的不错或者对您有所帮助的话

    不妨顶一个【微笑】,别忘了点赞、收藏、加关注哈

    看在我花了这么多时间整理写成文章分享给大家的份上,记得手下留情哈

    您的每个举动都是对我莫大的支持

    image

    相关文章

      网友评论

        本文标题:Android Rxjava+Retrofit网络请求框架封装(

        本文链接:https://www.haomeiwen.com/subject/vdebyqtx.html