Android retrofit2基本操作(草稿版)
retrofit底層實現是okhttp
retrofit就是對okhttp做了一層封裝。把網路請求都交給給了Okhttp,我們只需要通過簡單的配置就能使用retrofit來進行網路請求了。Retrofit框架存在的優勢:
① Retrofit使用註解方式,大大簡化了我們的URL拼寫形式,而且註解含義一目瞭然,簡單易懂;
② Retrofit使用簡單,結構層次分明,每一步都能清晰的表達出之所以要使用的寓意;
③ Retrofit支援同步和非同步執行,使得請求變得異常簡單,只要呼叫enqueue/execute即可完成;
④ Retrofit更大自由度的支援我們自定義的業務邏輯,如自定義Converters。
⑤ Retrofit支援多種檔案解析(Gson,Json,XML,Protobuf)
⑥ Retrofit支援RxJava
https://juejin.im/entry/57ce31b22e958a0054386d87
https://www.jianshu.com/p/308f3c54abdd
https://blog.csdn.net/lmj623565791/article/details/51304204
https://square.github.io/retrofit/
P.s.注意點
retrofit預設轉換string成json obj,如果不需要gson轉換,那麼就指定泛型為ResponseBody,不要設定gson轉換器
* 只能是ResponseBody,子類都不行,同理,下載上傳時,也必須指定泛型為ResponseBody
response.body().string() 呼叫一次,就釋放資源(也就是隻能呼叫一次)
https://blog.csdn.net/my_truelove/article/details/78998996
示例
public interface ZhailuData1 { @GET("api/v1/{id}") Call<ResponseBody> getZhailuData(@Path("id") String index); } //而不能是: @GET() Call<String> getZhailuData(@Path("id") String index); //如果這樣指定,意思是,使用retrofit內部的json轉換器,將response裡的資料轉換成一個實體類xxx,比如UserBean之類的,而String類明顯不是一個有效的實體類,自然轉換失敗.
-------------------------------------------------------------------------------------------------------------官網示例
GET
, POST
, PUT
, DELETE
, and HEAD
@GET("users/list")
@GET("users/list?sort=desc")
A replacement block is an alphanumeric string surrounded by {
and }
. A corresponding parameter must be annotated with @Path
using the same string.
@GET("group/{id}/users")
Call<List<User>> groupList(@Path("id") int groupId);
Query parameters can also be added.
@GET("group/{id}/users")
Call<List<User>> groupList(@Path("id") int groupId, @Query("sort") String sort);
For complex query parameter combinations a Map
can be used.
@GET("group/{id}/users")
Call<List<User>> groupList(@Path("id") int groupId, @QueryMap Map<String, String> options);
@POST("users/new")
Call<User> createUser(@Body User user);
@FormUrlEncoded
@POST("user/edit")
Call<User> updateUser(@Field("first_name") String first, @Field("last_name") String last);
@Multipart
@PUT("user/photo")
Call<User> updateUser(@Part("photo") RequestBody photo, @Part("description") RequestBody description);
@Headers("Cache-Control: max-age=640000")
@GET("widget/list")
Call<List<Widget>> widgetList();
@Headers({
"Accept: application/vnd.github.v3.full+json",
"User-Agent: Retrofit-Sample-App"
})
@GET("users/{username}")
Call<User> getUser(@Path("username") String username);
@GET("user")
Call<User> getUser(@Header("Authorization") String authorization)
By default, Retrofit can only deserialize HTTP bodies into OkHttp's ResponseBody
type and it can only accept its RequestBody
type for @Body
.
-------------------------------------------------------------------------------------------------------------官網示例
-------------------------------------------------------------------------------------------------------------常用操作
http://192.168.1.102:8080/springmvc_users/user/users
//用於訪問zhy的資訊
http://192.168.1.102:8080/springmvc_users/user/zhy
//用於訪問lmj的資訊
http://192.168.1.102:8080/springmvc_users/user/lmj
http://baseurl/users?sortby=username
http://baseurl/users?sortby=id
public interface IUserBiz
{
@GET("users")
Call<List<User>> getUsers();
}
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("http://192.168.31.242:8080/springmvc_users/user/")
.addConverterFactory(GsonConverterFactory.create())
.build();
IUserBiz userBiz = retrofit.create(IUserBiz.class);
Call<List<User>> call = userBiz.getUsers();
call.enqueue(new Callback<List<User>>()
{
@Override
public void onResponse(Call<List<User>> call, Response<List<User>> response)
{
Log.e(TAG, "normalGet:" + response.body() + "");
}
@Override
public void onFailure(Call<List<User>> call, Throwable t)
{
}
});
1. 介面中的方法必須有返回值,且比如是Call<T>型別
2. .addConverterFactory(GsonConverterFactory.create())這裡如果使用gson,需要額外匯入:
compile 'com.squareup.retrofit2:converter-gson:2.0.2'
3. 既然call.enqueue
是非同步的訪問資料,那麼同步的訪問方式為call.execute
,這一點非常類似okhttp的API,實際上預設情況下內部也是通過okhttp3.Call
實現。
public interface IUserBiz
{
@GET("{username}")
Call<User> getUser(@Path("username") String username);
}
Call<User> call = userBiz.getUser("zhy");
call.enqueue(new Callback<User>()
{
@Override
public void onResponse(Call<User> call, Response<User> response)
{
Log.e(TAG, "getUsePath:" + response.body());
}
}
public interface IUserBiz
{
@GET("users")
Call<List<User>> getUsersBySort(@Query("sortby") String sort);
}
Call<List<User>> call = userBiz.getUsersBySort("username");
public interface IUserBiz
{
@POST("add")
Call<List<User>> addUser(@Body User user);
}
Call<List<User>> call = userBiz.addUser(new User(1001, "jj", "123,", "jj123", "[email protected]"));
public interface IUserBiz
{
@POST("login")
@FormUrlEncoded
Call<User> login(@Field("username") String username, @Field("password") String password);
}
Call<User> call = userBiz.login("zhy", "123");
public interface IUserBiz
{
@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"));
public interface IUserBiz
{
@Multipart
@POST("register")
Call<User> registerUser(@PartMap Map<String, RequestBody> params, @Part("password") RequestBody password);
}
File file = new File(Environment.getExternalStorageDirectory(), "messenger_01.png");
RequestBody photo = RequestBody.create(MediaType.parse("image/png", file);
Map<String,RequestBody> photos = new HashMap<>();
photos.put("photos\"; filename=\"icon.png", photo);
photos.put("username", RequestBody.create(null, "abc"));
Call<User> call = userBiz.registerUser(photos, RequestBody.create(null, "123"));