Retorfit2在项目中的使用

Retorfit2在项目中的使用

这是我的Github地址:https://github.com/brokes6
我的博客:https://brokes6.github.io/

本篇已Java为主要语言

下面的代码为了方便,我将已我之前写的高仿B站的网络请求来进行讲解

源码地址 欢迎大家来star

  1. 添加依赖

    implementation 'com.squareup.retrofit2:retrofit:2.6.0'
    implementation 'com.squareup.retrofit2:converter-gson:2.4.0'
    implementation 'com.squareup.retrofit2:adapter-rxjava2:2.5.0'
    

    版本可能与官网版本存在不同,以官网为主

  2. 一般来说,使用了Retorfit2来进行网络请求,都会创建一个类用来进行retorfit初始化和一个接口文档来进行请求,下面我将创建一个“ApiEngine”类

    public class ApiEngine {
        private volatile static ApiEngine apiEngine;
        private Retrofit retrofit;
    
        private ApiEngine() {
    
            //添加网络拦截器
            NetWorkInterceptor netWorkInterceptor = new NetWorkInterceptor();
            //解析返回结果的Interceptor
            ResponseInterceptor responseInterceptor = new ResponseInterceptor();
    
            ClearableCookieJar cookieJar = new PersistentCookieJar(new SetCookieCache(), new SharedPrefsCookiePersistor(MyApplication.getContext()));
    
            //拦截器
            OkHttpClient client = new OkHttpClient.Builder()
                    .connectTimeout(20, TimeUnit.SECONDS)
                    .readTimeout(20, TimeUnit.SECONDS)
                    .writeTimeout(20, TimeUnit.SECONDS)
                    .addNetworkInterceptor(netWorkInterceptor)
                    .addInterceptor(responseInterceptor)
                    .addInterceptor(new AddCookiesInterceptor())
                	//下面这里是添加了自己定义的每次请求都会添加上Cookies
                    .addInterceptor(new ReceivedCookiesInterceptor())
                    .cookieJar(cookieJar)
                    .build();
    
            Gson gson = new Gson();
            //开启retrofit
            retrofit = new Retrofit.Builder()
                    //指定主url
                    .baseUrl(ApiService.BASE_URL)
                    //指定拦截器
                    .client(client)
                    //指定使用Gson解析
                    .addConverterFactory(GsonConverterFactory.create(gson))
                    //设置支持Observable
                    .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
                    .build();
        }
    
        //获取实例
        public static ApiEngine getInstance() {
            if (apiEngine == null) {
                synchronized (ApiEngine.class) {
                    if (apiEngine == null) {
                        apiEngine = new ApiEngine();
                    }
                }
            }
            return apiEngine;
        }
    
        public ApiService getApiService() {
            return retrofit.create(ApiService.class);
        }
    }
    

    并且这里设置成了单例模式,方便各个地方的获取

  3. 初始化完成了,接下来就是创建各个接口。下面我将创建一个"ApiService"来作为接口文档

    public interface ApiService {
    
        String BASE_URL = "xxxx";
        //这里是你服务器的地址和接口
    
        @GET("videoservice/video/{id}")
        Observable<VideoDetailsBean> getVideoDetails(@Path("id") int id, @Query("userId") int uid);
    
        @POST("videoservice/video/coin")
        Observable<CoinBean> coin_Operated(@Body dto coinBean, @Query("uid") int id);
    
        @POST()
        Observable<ThumbsUpBean> thumbsUp(@Url String url, @Body dto dto);
    
        @POST("userservice/login")
        Observable<UserBean> Login(@Body inputDto inputDto);
    
        @POST("userservice/user")
        Observable<RegisterBean> Register(@Body inputDto inputDto);
    
        @POST("videoservice/video/collection")
        Observable<CollectionBean> CollectionVideo(@Body dto dto, @Query("uid") int uid);
    
        @GET("userservice/logout")
        Observable<LogoutBean> Logout();
    
        @GET("commentservice/danmu/{vid}/{second}")
        Observable<DanmuBean> getDanMu(@Path("second") int second, @Path("vid") int vid);
    
        @POST("commentservice/danmu")
        Observable<SeadDanmuBean> seadDanMu(@Body danmu danmu);
    
        @GET("userservice/dynamic/unread")
        Observable<DynamicNumBean> getDynamicNum(@Query("uid") int uid);
    
        @GET
        Observable<VersionBean> getVersion(@Url String url);
    
        @POST("commentservice/comment")
        Observable<CommentBean> addComment(@Body dto dto, @Query("uid") int uid);
    
        @POST("commentservice/comment")
        Observable<CommentBean> addDynamicComment(@Body dto dto, @Query("uid") int uid);
    
        @GET("userservice/user/details/{uid}")
        Observable<UserBean> findUserDetails(@Path("uid") int uid);
    
        @GET("videoservice/banner/list")
        Observable<BannerBean> findBanner();
    
    }
    

    上面的网络请求路径是与服务器地址分开的,该文档只是负责不同的接口调用,接下来就介绍一下这里面的注释都是那些意思。拦截器的代码我就不放出来了,如果想要可去源码上获取

    注解说明
    @GETget请求
    @POSTpost请求
    @Headers用于添加固定请求头,可以同时添加多个。通过该注解添加的请求头不会相互覆盖,而是共同存在
    @Body多用于post请求发送非表单数据,比如想要以post方式传递json格式数据
    @Part用于表单字段,Part和PartMap与Multipart注解结合使用,适合文件上传的情况
    @Path用于url中的占位符
    @Query用于Get中指定参数
    @Url指定请求路径
  4. 接下来为了防止Activity过于繁杂,为了解耦,所以将以MVP模式来进行网络请求

MVP模式进行网络请求

MVP模式我就不做多介绍了,想要了解的返回看专门讲解的文档

结构介绍

  • contract 整体的接口
  • model 负责进行调用接口来获取数据
  • presenter view和model交互之间的桥梁
  • view 负责将获取的数据进行展示

接下来我已B站首页获取数据进行展示(源码在上方连接中)

  1. 先创建contract

    public interface RecommendContract {
        interface View extends BaseView {
    
            void onGetRecommendVideoSuccess(RecommendVideoBean videoBean);
    
            void onGetRecommendVideoFail(String e);
    
            void onGetRefreshRecommendVideoSuccess(RecommendVideoBean videoBean);
    
            void onGetRefreshRecommendVideoFail(String e);
    
            void onGetBannerSuccess(BannerBean bannerBean);
    
            void onGetBannerFail(String e);
    
        }
    
        interface Model extends BaseModel {
    
            Observable<RecommendVideoBean> getRandomRecommendation();
    
            Observable<RecommendVideoBean> getRefreshRecommendVideo();
    
            Observable<BannerBean> findBanner();
    
        }
    
        abstract class Presenter extends BasePresenter<View, Model> {
    
            public abstract void getRandomRecommendation();
    
            public abstract void getRefreshRecommendVideo();
    
            public abstract void findBanner();
        }
    }
    

    上面总共定义了4个方法,分别是:

    • 获取首页随机推荐
    • 刷新首页
    • 获取轮播图

    其中的View是给Activity/Fragment提供的接口,Model是给Model提供的接口,Presenter也就是给presenter提供的接口

  2. 按照顺序,接下来创建Model

    public class RecommendModel implements RecommendContract.Model {
        @Override
        public Observable<RecommendVideoBean> getRandomRecommendation() {
            return ApiEngine.getInstance().getApiService().randomRecommendation();
        }
    
        @Override
        public Observable<RecommendVideoBean> getRefreshRecommendVideo() {
            return ApiEngine.getInstance().getApiService().randomRecommendation();
        }
    
        @Override
        public Observable<BannerBean> findBanner() {
            return ApiEngine.getInstance().getApiService().findBanner();
        }
    }
    

    对应contract中的3个接口,每个接口对会去调用相应的接口并返回获取到的数据

  3. 最后创建Model与View之间的桥梁–presenter

    public class RecommendPresenter extends RecommendContract.Presenter {
        
        public void attachView(RecommendContract.View view) {
            this.mView = view;
            this.mModel = new RecommendModel();
        }
    
        public void detachView() {
            this.mView = null;
        }
    
        //这里是将Retrofit2与Rxjava一起使用
        //Retrofit2网络请求本身会自动的将网络请求放在子线程中运行,结果会在主线程中返回
        @Override
        public void getRandomRecommendation() {
            mModel.getRandomRecommendation().subscribeOn(Schedulers.io())
                    .observeOn(AndroidSchedulers.mainThread())
                    .subscribe(new Observer<RecommendVideoBean>() {
                        @Override
                        public void onSubscribe(Disposable d) {
    
                        }
    
                        @Override
                        public void onNext(RecommendVideoBean videoBean) {
                            mView.onGetRecommendVideoSuccess(videoBean);
                        }
    
                        @Override
                        public void onError(Throwable e) {
                            mView.onGetRecommendVideoFail(e.getMessage());
                        }
    
                        @Override
                        public void onComplete() {
    
                        }
                    });
        }
    
        @Override
        public void getRefreshRecommendVideo() {
            mModel.getRefreshRecommendVideo().subscribeOn(Schedulers.io())
                    .observeOn(AndroidSchedulers.mainThread())
                    .subscribe(new Observer<RecommendVideoBean>() {
                        @Override
                        public void onSubscribe(Disposable d) {
    
                        }
    
                        @Override
                        public void onNext(RecommendVideoBean videoBean) {
                            mView.onGetRefreshRecommendVideoSuccess(videoBean);
                        }
    
                        @Override
                        public void onError(Throwable e) {
                            mView.onGetRefreshRecommendVideoFail(e.getMessage());
                        }
    
                        @Override
                        public void onComplete() {
    
                        }
                    });
        }
    
        @Override
        public void findBanner() {
            mModel.findBanner().subscribeOn(Schedulers.io())
                    .observeOn(AndroidSchedulers.mainThread())
                    .subscribe(new Observer<BannerBean>() {
                        @Override
                        public void onSubscribe(@NonNull Disposable d) {
    
                        }
    
                        @Override
                        public void onNext(@NonNull BannerBean bannerBean) {
                            mView.onGetBannerSuccess(bannerBean);
                        }
    
                        @Override
                        public void onError(@NonNull Throwable e) {
                            mView.onGetBannerFail(e.getMessage());
                        }
    
                        @Override
                        public void onComplete() {
    
                        }
                    });
        }
    }
    

    上面的代码,都是通过调用model的接口将数据返回给对应View接口,这样View中就只需要调用方法,就可在对应的接口中获取数据

  4. 在Activity/Fragment中使用

    public class RecommendedFragment extends BaseFragment implements RecommendContract.View {
    	RecommendPresenter mPresenter;
        
        @Override
        protected View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState){
            ...
            //进行绑定
            mPresenter.attachView(this);
        }
        @Override
        protected void initData() {
             //调用接口来获取数据
             mPresenter.findBanner();
        }
        @Override
        public void onGetRecommendVideoSuccess(RecommendVideoBean videoBean) {
            //将获取到的数据放入适配器
            videoBean.addData(mBeanData);
            adapter.loadMore(videoBean.getData());
        }
    
        @Override
        public void onGetRecommendVideoFail(String e) {
        }
    
        @Override
        public void onGetRefreshRecommendVideoSuccess(RecommendVideoBean videoBean) {
            //刷新数据
            for (RecommendVideoBean.BeanData datum : videoBean.getData()) {
                adapter.add(0, datum);
            }
            binding.ReRecy.scrollToPosition(0);
        }
    
        @Override
        public void onGetRefreshRecommendVideoFail(String e) {
            //通知用户发送错误
            XToastUtils.error(R.string.errorOccurred + e);
        }
    
        @Override
        public void onGetBannerSuccess(BannerBean bannerBean) {
            mBeanData = new RecommendVideoBean.BeanData();
            mBeanData.setBanner(true);
            mBeanData.setBannerUrl(bannerBean.getData());
            mPresenter.getRandomRecommendation();
        }
    
        @Override
        public void onGetBannerFail(String e) {
    
        }
    
        @Override
        public void onDestroy() {
            //进行销毁
            mPresenter.detachView();
            super.onDestroy();
        }
    }
    

以上就是Retrofit2网络请求的全过程,下次会进一步的分析

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值