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

2019-06-17  本文已影响0人  l王小一

此篇文章主要记录下自己使用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来匹配

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

上一篇下一篇

猜你喜欢

热点阅读