Retrofit使用:
本文只讲Retrofit最基本的使用,文末有demo地址,参考资料如下:
http://blog.csdn.net/lmj623565791/article/details/51304204
http://square.github.io/retrofit/
https://www.jianshu.com/p/308f3c54abdd
https://www.cnblogs.com/qifengshi/p/6060520.html
PS:本文只是入门笔记,并不深入,大牛可以直接叉了~
1、Get请求:
- interface中的方法
@GET("{path}")
Call<Translation> getTranslation(@Path("path") String path,
@Query("appkey") String appkey,
@Query("chengyu") String chengyu);
- 请求体构造和返回
private void TestRetrofitGet() {
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("http://api.jisuapi.com/chengyu/")
.addConverterFactory(GsonConverterFactory.create())
.build();
ITranslationBiz translationBiz = retrofit.create(ITranslationBiz.class);
Call<Translation> call = translationBiz.getTranslation(
"detail",
"b26bb56628f89b47",
mEt.getText().toString().trim());
call.enqueue(new Callback<Translation>() {
@Override
public void onResponse(Call<Translation> call, Response<Translation> response) {
Translation translation = response.body();
if (translation == null) {
return;
}
String result = "成语名称:" + translation.getResult().getName() + "\n"
+ "读音:" + translation.getResult().getPronounce() + "\n"
+ "解释:" + translation.getResult().getContent() + "\n"
+ "出自:" + translation.getResult().getComefrom() + "\n"
+ "反义词:" + translation.getResult().getAntonym() + "\n"
+ "近义词:" + translation.getResult().getThesaurus() + "\n"
+ "例子:" + translation.getResult().getExample() + "n\";";
mTv.setText(result);
}
@Override
public void onFailure(Call<Translation> call, Throwable t) {
mTv.setText(t.getMessage());
}
});
}
第一步:
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("http://api.jisuapi.com/chengyu/")
.addConverterFactory(GsonConverterFactory.create())
.build();
/*通过以上代码,可以简单的构建一个retrofit对象,addConverterFactory是对response进行解析,里面添加的参数是表示对response用String解析,然后添加一个基础的URL,后续的参数则是通过上面我们定制的接口来添加,最后构建一个完整的URL。*/
第二步:
ITranslationBiz translationBiz = retrofit.create(ITranslationBiz.class);
/*通过动态代理,生成一个接口的对象.*/
第三步:
Call<Translation> call = translationBiz.getTranslation(
"detail",
"b26bb56628f89b47",
mEt.getText().toString().trim());
//通过接口的方法得到调用的对象,泛型为实例
PS:
@GET:
- 中所填写的value和baseUrl组成完整的路径
- @GET中value如果用”{path}”括起来,则表示占位符,从方法中的@Path对应的参数取出来,@Path(“path”)中的参数必须和占位符一致,如:都为path
- retrofit非常适用于restful url的格式,如:
//用于访问zhy的信息 http://192.168.1.102:8080/springmvc_users/user/zhy //用于访问lmj的信息 http://192.168.1.102:8080/springmvc_users/user/lmj
通过不同的username访问不同用户的信息,那么可以通过retrofit提供的@PATH注解非常方便的完成上述需求。@Path只能进入url的path部分的占位,不能在参数部分占位。官方的Get请求例子如下:
public interface GitHubService { @GET("users/{user}/repos") Call<List<Repo>> listRepos(@Path("user") String user); }
- @Query表示请求传递的参数,不可用表单的@Field否则会报一个异常,如果是表单传参还必须是Post请求才行,注解用@Field。如果参数较多较复杂,可以使用一个键值对map,注解为:@QueryMap,官方例子,和我的Demo如下:
@GET("group/{id}/users")
Call<List<User>> groupList(@Path("id") int groupId, @QueryMap Map<String, String> options);
@GET("{path}")
Call<Translation> getTranslationByQueryMap(@Path("path") String path,
@QueryMap Map<String, String> queryOptions);
- Retrofit的构造:
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("http://api.jisuapi.com/chengyu/")
.addConverterFactory(GsonConverterFactory.create())
.build();
- 得到接口类的实例:
ITranslationBiz translationBiz = retrofit.create(ITranslationBiz.class);
- 得到call回调:
Call<Translation> call = translationBiz.getTranslationByQueryMap(
"detail",
queryOptions);
Call<Translation>,显然这里用到了泛型,和接口的方法返回值一致.
那么我们不仅可以得到一个对象,还可以得到一个对象列表,如返回值为:
Call<List<Translation>>
- call.enqueue()异步执行:
call.enqueue(new Callback<Translation>() {
@Override
public void onResponse(Call<Translation> call, Response<Translation> response) {
Translation translation = response.body();
if (translation == null) {
return;
}
String result = "成语名称:" + translation.getResult().getName() + "\n"
+ "读音:" + translation.getResult().getPronounce() + "\n"
+ "解释:" + translation.getResult().getContent() + "\n"
+ "出自:" + translation.getResult().getComefrom() + "\n"
+ "反义词:" + translation.getResult().getAntonym() + "\n"
+ "近义词:" + translation.getResult().getThesaurus() + "\n"
+ "例子:" + translation.getResult().getExample() + "n\";";
mTv.setText(result);
}
@Override
public void onFailure(Call<Translation> call, Throwable t) {
mTv.setText(t.getMessage());
}
});
这里response.body()即为json转换后的实例对象,与Call和Response两个的泛型一致
写到这里一个Get方法就讲Retrofit的基本用法涵盖了,不过在开发中可能还有更多的需求,更多用法如下:
2、Post请求:
@Path、@Query、@QueryMap用法基本与Get请求一样
- 请求体@Body,官网示例如下:
//官网解释如下:对象也将使用改进实例中指定的转换器进行///转换,如GsonConvert可以将对象转化为json字符串
//如果没有添加器,只有requestbody可用。
@POST("users/new")
Call<User> createUser(@Body User user);
- 表单的方式传递键值对@FormUrlEncoded,官网示例:
//需要注意的是,如果是表单数据,必须有这两个注解
//@FormUrlEncoded,@POST("user/edit")否则会报异常
@FormUrlEncoded
@POST("user/edit")
Call<User> updateUser(@Field("first_name") String first, @Field("last_name") String last);
- 单文件上传@Multipart:
/*
这里@MultiPart的意思就是允许多个@Part了,
我们这里使用了3个@Part,第一个我们准备上传个文件,
使用了MultipartBody.Part类型,其余两个均为简单的键值对。
*/
@Multipart
@POST("register")
Call<User> registerUser(@Part MultipartBody.Part photo, @Part("username") RequestBody username, @Part("password") RequestBody password);
//回调如下:
File file = new File(Environment.getExternalStorageDirectory(), "icon.png");
RequestBody photoRequestBody = RequestBody.create(MediaType.parse("image/png"), file);
MultipartBody.Part photo = MultipartBody.Part.createFormData("photos", "icon.png", photoRequestBody);
Call<User> call = userBiz.registerUser(photo, RequestBody.create(null, "abc"), RequestBody.create(null, "123"));
/*
RequestBody.create(MediaType.parse("image/png"), file)表示生成一个文件part
RequestBody.create(null, "abc")表示生成一个简单的键值对part
很明显和create方法的第一个参数有关
*/
多文件上传:参考:
https://www.jianshu.com/p/acfefb0a204f
demo展示:
其他没有说到地方请看资料
另附上demo地址:https://github.com/tupobi/TestRetrofitDemo