美文网首页
Android | Retrofit简单封装及注解的使用

Android | Retrofit简单封装及注解的使用

作者: l王小一 | 来源:发表于2019-06-17 17:19 被阅读0次

    此篇文章主要记录下自己使用Retrofit后简易的封装,和相对全面的请求类型的注解使用方法,也是对知识点的一个总结和复习。

    Retrofit是什么?

    简单来说Retrofit是一个网络请求框架,基于OkHttp做了进一步封装,更好的适用于RESTful URL格式风格,通过注解配置参数,可以灵活的设置URL、请求头、请求体等。

    优点

    • 超级解耦
    • 处理速度快
    • 使用灵活方便
    • 可以使用注解控制请求的参数

    封装

    public class RetrofitManager {
        private static RetrofitManager mRetrofitManager;
        private Retrofit mRetrofit;
        private static Context mContext;
    
        public RetrofitManager(Context context) {
            this.mContext = context;
            initRetrofit();
        }
    
        public static synchronized RetrofitManager getInstance(){
            if (mRetrofitManager == null){ mRetrofitManager = new RetrofitManager(mContext);}
            return mRetrofitManager;
        }
    
        private void initRetrofit(){
            OkHttpClient.Builder builder = new OkHttpClient.Builder();
            //添加拦截器
            builder.addInterceptor(new ResponseInterceptor ());
            builder.addInterceptor(new RequestInterceptor ());
            OkHttpClient client = builder
                    //设置请求超时时间
                    .connectTimeout(30, TimeUnit.SECONDS)
                    .readTimeout(30, TimeUnit.SECONDS)
                    .writeTimeout(30, TimeUnit.SECONDS)
                    .build();
    
            mRetrofit = new Retrofit.Builder()
                    .baseUrl(AlderApiService.BASE_URL)
                    // addConverterFactory 对服务器数据进行解析
                    .addConverterFactory(GsonConverterFactory.create())//利用Gson解析返回的json
                    .addConverterFactory(ScalarsConverterFactory.create())
                    .client(client)
                    .build();
        }
    
        public <T> T createReq(Class<T> reqServer){
            return mRetrofit.create(reqServer);
        }
    }
    

    一般使用时只用调用这个类就行了,这里主要添加了请求的拦截器、设置请求的超时时间、对添加请求的base url、添加对服务器返回数据的解析。

    拦截器

    public class ResponseInterceptor implements Interceptor {
        private final String TAG = "ResponseInterceptor ";
    
        @Override
        public Response intercept(Chain chain) throws IOException {
            Response response = chain.proceed(chain.request());
            if(response!= null){
                if ( response.header("token") != null ){
                    //获取请求头中的token 并保存在sp中
                    final String token = response.header("token");
                    SharedPreferencesUtils.getInstance().putString(SharedPreferencesUtils.TOKEN,token);
                    Log.e(TAG,"保存在本地的token为:"+token);
                }
            }
            return response;
        }
    }
    

    获取Response的请求头内容,项目里只用到了token,所以这里只获取了token进行保存。

    public class RequestInterceptor implements Interceptor {
    
        }
    }    private final String TAG = "RequestInterceptor ";
    
        @Override
        public Response intercept(Chain chain) throws IOException {
    
            final Request.Builder builder = chain.request().newBuilder();
    
            String token = SharedPreferencesUtils.getInstance().getString(SharedPreferencesUtils.TOKEN,"");
            if (!token.isEmpty()&& null!=token&& !"".equals(token)){
                //添加请求头,携带token
                builder.addHeader("token",token);
                Log.i(TAG,"携带的本地token为:"+token);
            }
            return chain.proceed(builder.build());
    
    

    给Request请求头中添加token。

    Retrofit Service

    我是主要在这里管理各个请求和base url,贴个图,大概格式就是这样


    image.png

    封装好后该如何使用?

    简单粗暴上代码

     public void registerSubmit(String name,String pwd,String email){
            mIRegisterView.showSubmitWaitDialog();
            RetrofitManager retrofitManager = new RetrofitManager(mContext);
            AlderApiService.RegisterService registerService = retrofitManager.createReq(AlderApiService.RegisterService.class);
            Call<Result> requestBodyCall = registerService.register(name,pwd,email);
            requestBodyCall.enqueue(new Callback<Result>() {
                @Override
                public void onResponse(Call<Result> call, Response<Result> response) {
                    mIRegisterView.dismissSubmitWaitDialog();
                    Result result = response.body();
                    Log.i(TAG,"result : "+result.toString());
                    if(response.body() != null){
                        if (result.isResult()){
                         //success
                        }else {
                        //fail
                        }
                    }else {
                        mIRegisterView.OnRegisterFailed(ErrorCode.REQUEST_BODY_ERROR);
                    }
                }
    
                @Override
                public void onFailure(Call<Result> call, Throwable t) {
                    mIRegisterView.dismissSubmitWaitDialog();
                    mIRegisterView.OnRegisterFailed(ErrorCode.NETWORK_ERROR);
                }
            });
    
        }
    

    注解的使用

    下面列举的不是全部的注解,只是列举了在不同请求中遇到过使用过的注解。

    POST请求

    1. 普通的表单格式提交

    @FormUrlEncoded  表单格式
    @POST            post请求方式
    @Field           表单提交参数
    

    一般这三个注解会一起使用,例如:

       @FormUrlEncoded
       @POST("v1/user/login")
       Call<Result> login(@Field("userName") String userName);
    

    这里@Field 中的userName是接口中定义的参数名,后面的userName是本地调用时传的参数


    2. 提交json格式

    @Headers  添加请求头
    @Body     请求携带的参数(对象类型)
    

    这里添加请求头和我们前面在拦截器中添加都可以,因为这个请求方式是极少数,所以只是在这里单独添加,内容类型为json

    @Headers({"Content-Type:application/json","Accept: application/json"})
    @POST("v1/user/remove")
    Call<Result> deleteUser(@Body RequestBody requestBody);
    

    @Body 就是传入的参数为RequestBody类型

    这个方法调用时传入的参数为这样

    RequestBody body=RequestBody.create(okhttp3.MediaType.parse("application/json; charset=utf-8"),json.toString());
    

    一般这种提交是用在批量删除的时候,将id集合以json的形式提交。

    3. 路径中携带参数

    @Path   将参数放在路径中
    
     @FormUrlEncoded
     @POST("v1/panel/{imei}")
     Call<Result<Integer>> armControl(@Path("imei") String imei,@Field("armingLevel") int armingLeve);
    

    @Path 有一些提交的参数是明文提交,也就是直接在url路径中显示的,这时用到的注解就是TA

    GET请求

    1. 普通get

    @GET   get请求方式
    
     @GET("v1/user/info")
     Call<Result<AccountInformation>> getAccount();
    

    @GET 这个注解就不用做过多解释了,和post为两种请求方式

    2. 带参get请求①

    @GET("v1/camera/{deviceID}")
    Call<GetCamera> getCameraInfo(@Path("deviceID") Integer deviceID);
    

    这里有用到@Path,用法其实是一样的,在url中携带参数。

    3. 带参get请求②

    @Query         请求携带参数
    @QueryMap      请求携带参数集合
    
     @GET("v1/notification")
     Call<Result<Map<String,List<Notification>>>> getNotification(@Query("cameraId") String cameraId);
    

    @Query 在一定意义上和@Path是差不多的,最终的参数都是在请求的url中,@Query 是不需要我们自己在url中写参数的key,url最终的效果是v1/notification?cameraId=xxx,用上面的栗子来看的话 @Path url最终的效果是v1/camera/xx

    DELETE请求

     @DELETE   删除
    
     @DELETE("rest/{deviceID}")
     Call<String> deleteCamera(@Path("deviceID") String deviceID);
    

    一般这样的操作,在后台提供的接口时也需要使用RESTful风格中的@DELETE来匹配

    目前在项目中常用的一些注解和封装方法就酱紫啦,写的比较基础,也没有实在性的技术语言去讲解,但把如何使用的例子都贴的很清楚,我觉得有些东西能说出来并不一定会用,但是当你会用了就一定能说,不应该把对技术的学习停留在理论上 -.而且对于菜鸟的我来说,在网上查到的一些结束贴,大部分都是文字说明文字说明文字说明....看的到最后头大了都不知道该怎么去用,把怎么用讲清楚最实在。
    还有很多注解没有写到,等以后用了再继续补充~~
    希望在技术的路上越走越好~~

    相关文章

      网友评论

          本文标题:Android | Retrofit简单封装及注解的使用

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