Retrofit2.0初识

其实关于 Retrofit2.0 网上的介绍已经很多了,这里我只是根据众多资料以及自己使用之后写点自己的想法,本篇文章参考以下链接:


1.  Retrofit 2.0非常简单的入门(翻译官方文档):http://www.jianshu.com/p/442a29da7b23
2. Retrofit 官网:http://square.github.io/retrofit/
3. Retrofit2.0使用总结:http://www.jianshu.com/p/3e13e5d34531
在此感谢!
下面对 Retrofit2.0做简单讲解:
首先,添加 网络链接权限
<uses-permission android:name="android.permission.INTERNET" />

app 的 build.gradle 中添加依赖包,由于解析过程中用到Gson,故也要添加 gson 依赖
   
compile 'com.squareup.retrofit2:retrofit:2.2.0'
    compile 'com.squareup.retrofit2:converter-gson:2.2.0'


Retrofit2.0的使用分三步:
1.写url接口类
2.写Retrofit对象,并配置网络
3.编写调用网络通讯方法


OK,首先讲第一步,先命名一个接口类,用于放众多的url,类似如下:
public interface ApiService<T>{


    //注册时获取短信验证码
    @POST("api/login/pushSms")
    @FormUrlEncoded
    Call<ApiResponse<SmsCode>> postSms(@FieldMap Map<String, String> map);
}



下面对 Retrofit2.0 的注解做些解释,注解一般分为:
方法注解,包含@GET、@POST、@PUT、@DELETE、@PATH、@HEAD、@OPTIONS、@HTTP。
标记注解,包含@FormUrlEncoded、@Multipart、@Streaming。
参数注解,包含@Query,@QueryMap、@Body、@Field,@FieldMap、@Part,@PartMap。
其他注解,@Path、@Header,@Headers、@Url


下面做具体讲解:

@HTTP:可以替代其他方法的任意一种

   /**
     * method 表示请的方法,不区分大小写
     * path表示路径
     * hasBody表示是否有请求体
     */
    @HTTP(method = "get", path = "users/{user}", hasBody = false)
    Call<ResponseBody> getFirstBlog(@Path("user") String user);

//=============== URL操作 =================================


    //@Url:使用全路径复写baseUrl,适用于非统一baseUrl的场景。
    @GET
    Call<ResponseBody> getInfo(@Url String url);
   
    //当请求的url中含动态字符串参数时,用@Path表示请求参数
    @GET("users/{user}/repos")
    Call<List<T>> listRepos(@Path("user") String user);

    //你也可以将query参数直接写在URL里静态传输
    @GET("users/list?sort=desc")
    Call<String>getResponse();

    //Query参数也能同时添加
    @GET("group/{id}/users")
    Call<List<T>> groupList(@Path("id") int groupId, @Query("sort") String sort);

    //复杂的query参数可以用Map来构建
    @GET("group/{id}/users")
    Call<List<T>> groupList(@Path("id") int groupId, @QueryMap Map<String, String> options);

//=============== 请求主体 =================================


    //能够通过@Body注解来指定一个方法作为HTTP请求主体,这个参数对象会被Retrofit实例中的converter进行转化。
    // 如果没有给Retrofit实例添加任何converter的话则只有RequestBody可以作为参数使用
    @POST("users/new")
    Call<User> createUser(@Body User user);

    //可以通过@FormUrlEncoded注解方法来发送form-encoded的数据。
    // 每个键值对需要用@Filed来注解键名,随后的对象需要提供值。(直接传key-value参数)
    @FormUrlEncoded
    @POST("user/edit")
    Call<User> updateUser(@Field("first_name") String first, @Field("last_name") String last);

    //也可以通过@Multipart注解方法来发送Mutipart请求。每个部分需要使用@Part来注解。
    //多个请求部分需要使用Retrofit的converter或者是自己实现 RequestBody来处理自己内部的数据序列化
    @Multipart
    @PUT("user/photo")
    Call<User> updateUser(@Part("photo") RequestBody photo, @Part("description") RequestBody description);

   //@Streaming:用于下载大文件
    @Streaming
    @GET
    Call<ResponseBody> downloadFileWithDynamicUrlAsync(@Url String fileUrl);

//    @Part,@PartMap:用于POST文件上传
//    其中@Part MultipartBody.Part代表文件,@Part("key") RequestBody代表参数
//    需要添加@Multipart表示支持文件上传的表单,Content-Type: multipart/form-data
    @Multipart
    @POST("upload")
    Call<ResponseBody> upload(@Part("description") RequestBody description,
                              @Part MultipartBody.Part file);
    // https://github.com/iPaulPro/aFileChooser/blob/master/aFileChooser/src/com/ipaulpro/afilechooser/utils/FileUtils.java
    // use the FileUtils to get the actual file by uri
    File file = FileUtils.getFile(this, fileUri);


    // create RequestBody instance from file
    RequestBody requestFile =
            RequestBody.create(MediaType.parse("multipart/form-data"), file);


    // MultipartBody.Part is used to send also the actual file name
    MultipartBody.Part body =
            MultipartBody.Part.createFormData("picture", file.getName(), requestFile);


    // add another part within the multipart request
    String descriptionString = "hello, this is description speaking";
    RequestBody description =
            RequestBody.create(
                    MediaType.parse("multipart/form-data"), descriptionString);


//=============== 请求头部 ======================= 


//你可以通过使用@Headers注解来设置请求静态头。 

 @Headers("Cache-Control: max-age=640000") 
 @GET("widget/list") Call<List<User>> widgetList(); 

//注意的是头部参数并不会相互覆盖,同一个名称的所有头参数都会被包含进请求里面。 
@Headers({ "Accept: application/vnd.github.v3.full+json", "User-Agent: Retrofit-Sample-App" }) 
@GET("users/{username}") Call<User> getUser(@Path("username") String username); 

//你可以通过 @Header 注解来动态更新请求头。一个相应的参数必须提供给 @Header 注解。 
// 如果这个值是空(null)的话,那么这个头部参数就会被忽略。 
// 否则的话, 值的 toString 方法将会被调用,并且使用调用结果。 
@GET("user") Call<User> getUsers(@Header("Authorization") String authorization);


然后是编写 Retrofit 对象类:

public class HttpClient{
    private ApiService mApiService;
    private static HttpClient mInstance;
    private HttpClient(){
        String baseUrl = HttpConfig.getUrl();
        Retrofit retrofit = new Retrofit.Builder()
                //添加url
                .baseUrl(baseUrl)
                //添加gson解析
                .addConverterFactory(GsonConverterFactory.create())
                .build();
        mApiService = retrofit.create(ApiService.class);
    }

    public static HttpClient getInstance(){
        if(mInstance==null){
            mInstance=new HttpClient();
        }
        return mInstance;
    }

    public ApiService getApiService(){
        return mApiService;
    }
}


http 配置类

public class HttpConfig {

    private static boolean IS_DEBUG=true;
    private static String mBaseUrl=null;
    private static final String TEST_URL="https://api.github.com/";
    private static final String RELEASE_URL="";
    public static String getUrl(){
        if(IS_DEBUG){
            mBaseUrl=TEST_URL;
        }else{
            mBaseUrl=RELEASE_URL;
        }
        return mBaseUrl;
    }
}

现在以 发送一个获取 短信的通讯为例:
接口类中声明 url:

 //注册时获取短信验证码
    @POST("api/login/pushSms")
    @FormUrlEncoded
    Call<ApiResponse<SmsCode>> postSms(@FieldMap Map<String, String> map);
ApiResponse和SmsCode 均为 实体model
在 activity中发起通讯并接收结果:

 private void send(Map<String,String>map){
        HttpClient.getInstance().getApiService().postSms(map).enqueue(new Callback<ApiResponse<SmsCode>>() {
            @Override
            public void onResponse(Call<ApiResponse<SmsCode>>call, Response<ApiResponse<SmsCode>>response) {
                int code=response.code();
                ApiResponse apiResponse=response.body();
                SmsCode sms= (SmsCode) apiResponse.getData();

                Log.e(TAG, "sms: "+sms.getStatus());
            }


            @Override
            public void onFailure(Call call, Throwable t) {
                Log.e(TAG, "t"+t.getMessage());
            }
        });
    }

activity中点击 button 的时候,调用 send 方法并传入 map 参数即可,通讯返回结果如下:

test E/pei: sms: -1
test E/pei: code: ApiResponse{code=0, message='请求失败', data=com.test.model.SmsCode@61b3d8d}
test E/pei: code: 200


最后是关于Retrofit2.0的混淆

-dontwarn retrofit2.**
-keep class retrofit2.** { *; }
-keepattributes Signature
-keepattributes Exceptions


其实关于 Retrofit2.0,如果不需要对网络通讯做特殊处理,是不需要引入 okhttp3的,因为 Retrofit2.0 本身就是对 Okhttp3的一个封装,这是需要注意的。


ok,今天对于 Retrofit2.0 的讲解就到这里,感谢!
















评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值