Retrofit使用总结
2018-01-04 13:48
176 查看
相关内容介绍:
概述如何使用
同步请求
异步请求
如何取消
各种路径 @Path @Query 等的如何 以及详细使用 Url 是什么样子
如何添加Converter modules 类型转换器 可以转换哪些类型
其他内容
自定义Gson对象
新的URL定义方式
Use an Interceptor from OkHttp(okhttp 使用拦截器)
RxJava Integration with CallAdapter(使用rxjava)
概述
Retrofit是由Square公司出品的针对于Android和Java的类型安全的Http客户端Retrofit 实际上就是对okHttp的封装
较1.9 旧版本区别
新的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-gsonJackson: 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.re ae27 trofit2: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 拦截器
相关文章推荐
- Retrofit2.0使用总结及注意事项
- Android 网络请求框架 Retrofit2.0实践使用总结
- Retrofit使用总结
- Retrofit2.0简单使用总结
- Retrofit使用总结
- Retrofit2.0使用总结及注意事项
- Retrofit2.0使用总结及注意事项
- Retrofit2.0使用总结
- Retrofit使用总结
- Retrofit 2.0 使用总结
- Retrofit2.0使用总结
- Retrofit2.0使用总结及注意事项
- android Retrofit2+okHttp3使用总结
- Retrofit2.0使用总结及注意事项
- Retrofit2.0使用总结
- Retrofit三步理解之一 ------------------ Retrofit的简单使用总结
- Retrofit使用总结
- Retrofit2使用总结
- Retrofit使用场景总结
- Retrofit使用总结