Retrofit使用总结

相关内容介绍:
  1. 概述
  2. 如何使用
    • 同步请求
    • 异步请求
    • 如何取消
  3. 各种路径 @Path @Query 等的如何 以及详细使用 Url 是什么样子
  4. 如何添加Converter modules 类型转换器 可以转换哪些类型

  5. 其他内容

    • 自定义Gson对象
    • 新的URL定义方式
    • Use an Interceptor from OkHttp(okhttp 使用拦截器)
    • RxJava Integration with CallAdapter(使用rxjava)
概述
  • Retrofit是由Square公司出品的针对于Android和Java的类型安全的Http客户端
  • Retrofit 实际上就是对okHttp的封装
较1.9 旧版本区别
  1. 新的Service定义方式,不再有同步和异步之分
    Retrofit 2.0 上,只能定义一个模式,因此要简单得多。

    import retrofit.Call;
        public interface APIService {       
        /* Retrofit 2.0 */    
            @POST("/list")      
            Call<Repo> loadRepo();
        }
    

调用同步请求,只需调用execute,而发起一个异步请求则是调用enqueue.

    Call<Repo> call = service.loadRepo();
    Repo repo = call.execute();

以上的代码会阻塞线程,因此你不能在安卓的主线程中调用,不然会报错 NetworkOnMainThreadException. 如果你要调用execute 方法,请在后台线程执行。

    Call<Repo> call = service.loadRepo();
    call.enqueue(new Callback<Repo>(){
            @Override
            publicvoid onResponse(Response<Repo> response){
            }

            @Override
            publicvoid onFailure(Throwable t){
            }
    });

2.
取消正在进行中的业务
service 的模式变成Call的形式的原因是为了让正在进行的事务可以被取消。要做到这点,你只需调用

    call.cancel()。

事务将会在之后立即被取消。

请求时 ,如果你的在baseUrl 后面没有后续的 Path 只是一个类似百度(http://www.baidu.com) 这样的一个请求,@GET 会报错 missing @GET 或者 @URL 我们可以是用这样的方式来解决(亲测可行)。

@GET("/")
Call<ResponseBody> getBaiduInfo();
retrofit 注解

方法注解,包含@GET、@POST、@PUT、@DELETE、@PATH、@HEAD、@OPTIONS、@HTTP。
标记注解,包含@FormUrlEncoded、@Multipart、@Streaming。
参数注解,包含@Query,@QueryMap、@Body、@Field,@FieldMap、@Part,@PartMap。
其他注解,@Path、@Header,@Headers、@Url


@HTTP:可以替代其他方法的任意一种(baseUrl :http://gank.io/api/

@HTTP(method = "GET", path = "data/{type}/{num}/{page}", hasBody = false)
Call<GankTypeEntity> getGankDataByHttp(@Path("type") String type, @Path("num") int num, @Path("page") int page);

@GET 请求(baseUrl :http://gank.io/api/

@GET("data/{type}/{num}/{page}")
Call<GankTypeEntity> getGankDataByGet(@Path("type") String type, @Path("num") int num, @Path("page") int page);

@Url : 传入一个完整的url(如:http:\www.baidu.com/) 。 会覆盖baseUrl 。适用于baseUrl不统一的情景下。

@GET
Call<ResponseBody> getBaiduInfo(@Url String url);

@Streaming:用于下载大文件(亲测可行,app内的apk下载地址,未能提供链接)

@Streaming
@GET
Call<ResponseBody> downloadFile(@Url String url);

@Query,@QueryMap:查询参数,用于GET查询,需要注意的是@QueryMap可以约定是否需要encode

@GET("users")
Call<List<GithubUser>> getUserByGroup(@Query("groupId")int groupId);

Call<List<News>> getNews((@QueryMap(encoded=true) Map<String, String> options); (未验证)

@Body:用于POST请求体,将实例对象根据转换方式转换为对应的json字符串参数,
这个转化方式是GsonConverterFactory定义的。

 @POST("add")
 Call<List<User>> addUser(@Body User user);

@Field,@FieldMap:Post方式传递简单的键值对,(baseUrl :http://gank.io/api/
需要添加@FormUrlEncoded表示表单提交 否则会报错

@Field parameters can only be used with form encoding. (parameter #1)Content-Type:application/x-www-form-urlencoded

@FormUrlEncoded
@POST("add2gank")
Call<ResponseBody>  postContent(@Field("url")String url,@Field("desc") String desc,@Field("who")String who,@Field("type")String type,@Field("debug")String debug);

@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);

@Header:header处理,不能被互相覆盖,用于修饰参数,

//动态设置Header值
@GET("user")
Call<User> getUser(@Header("Authorization") String authorization)

也可以

//静态设置Header值
@Headers("Authorization: authorization")
//这里authorization就是上面方法里传进来变量的值
@GET("widget/list")Call<User> getUser()

@Headers 用于修饰方法,用于设置多个Header值:

@Headers({    "Accept: application/vnd.github.v3.full+json",    "User-Agent: Retrofit-Sample-App"})
@GET("users/{username}")
Call<User> getUser(@Path("username") String username);
Gson使用

需要导入以下依赖:

    compile 'com.squareup.retrofit2:converter-gson:2.3.0'

以下为代码中使用方式:

mRetrofit = new Retrofit.Builder()
        .baseUrl("http://www.baidu.com/")
        .client(client)
        .addConverterFactory(GsonConverterFactory.create(gson)) 
        .build();

retrofit其他

Retrofit 支持的Converter modules 列表

Gson: com.squareup.retrofit:converter-gson
Jackson: com.squareup.retrofit:converter-jackson
Moshi: com.squareup.retrofit:converter-moshi
Protobuf: com.squareup.retrofit:converter-protobuf
Wire: com.squareup.retrofit:converter-wire
Simple XML: com.squareup.retrofit:converter-simplexml

url 问题

baseUrl 必须以“/” 结尾 否则会报错

在Retrofit2.0中,我们还可以在@Url里面定义完整的Url :

    @GET("http://www.baidu.com/")
    Call<ResponseBody> getBaiduInfo();

这样情况下,baseUrl 会被覆盖掉

拒绝encode

okHttp 默认会对Query 的参数进行编码 , 但是某些特殊的情况,我们并不希望如此。我们可以使用以下方式

@Query(value = "tag", encoded = false) String tag
OkHttp的支持

在Retrofit 2.0中,OkHttp 是必须的,并且自动设置为了依赖。下面的代码是从Retrofit 2.0的pom文件中抓取的。你不需要再做任何事情了。

    <dependencies>  
        <dependency>    
            <groupId>com.squareup.okhttp</groupId>   
             <artifactId>okhttp</artifactId> 
         </dependency>  ...
    </dependencies>
添加拦截器( 拦截器的具体使用后面的博客还会继续介绍 )
    client = new OkHttpClient.Builder()
            .retryOnConnectionFailure(true)
            .addInterceptor(new Interceptor() {
                @Override
        public Response intercept(Chain chain) throws IOException {
                    Log.e("testBaidu","我这里是拦截器");
            Response proceed = chain.proceed(chain.request());
            return proceed;
        }
            })
            .connectTimeout(15, TimeUnit.SECONDS)
            .build();
Rxjava Retrofit使用

使用Rxjava 需要导入以下依赖:

    compile 'com.squareup.retrofit2:adapter-rxjava2:2.3.0'
    compile 'io.reactivex.rxjava2:rxandroid:2.0.1'

下一步,在Retrofit Builder模式的列表中 调用addCallAdapterFactory:

    mRetrofit = new Retrofit.Builder()
            .baseUrl("http://www.baidu.com/")
            .client(client)
            .addConverterFactory(GsonConverterFactory.create(gson))
            .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
            .build();

RxJava 相关代码(RxJava 此处指是提及,后续还会有博客进行详细介绍)

    Observable<ResponseBody> baiduInfo =         manageService.getBaiduInfo();

    baiduInfo
            .subscribeOn(Schedulers.io())
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe(new Observer<ResponseBody>() {
                @Override
        public void onSubscribe(Disposable d) {

                }

                @Override
        public void onNext(ResponseBody value) {
                    try {
                        Log.e("testBaidu", value.string());
            } catch (IOException e) {
                    }
                }

                @Override
        public void onError(Throwable e) {
                    Log.e("testBaidu","error ");
        }

                @Override
        public void onComplete() {
                    Log.e("testBaidu", "onComplete");
        }
            });

注意如果需要访问网络, 则 Schedulers.io 是必须的。否则就会报错。

相关参考资料

Retrofit2.0使用总结
Okhttp-wiki 之 Interceptors 拦截器

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值