前言
Retrofit是一個(gè)網(wǎng)絡(luò)請(qǐng)求李丰,用法簡(jiǎn)潔方便,一起來學(xué)習(xí)一下吧O(∩_∩)O~
一、配置
工具是 Android Studio罢荡,所以這里只講AndroidStudio的配置
**1. build.gradle **
首先紧索,如圖添加retrofit和okhttp
compile 'com.squareup.retrofit2:retrofit:2.2.0'
compile 'com.squareup.okhttp3:okhttp:3.6.0'
2. 添加網(wǎng)絡(luò)權(quán)限
<uses-permission android:name="android.permission.INTERNET"/>
二菜谣、靜態(tài)參數(shù)接口GET請(qǐng)求
接口用http://gank.io/api/data/Android/10/1這個(gè)
然后晚缩,我們就開始獲取數(shù)據(jù)啦~
1. 定義一個(gè)接口類
這個(gè)接口我們用https://..com/goods/tags/goods/1?g_id=0
public interface Api {
@GET("goods/tags/goods/1?g_id=0")
Call<ResponseBody> getData(); //retrofit下的call
}
2. 開始請(qǐng)求
接口需要大家自己找一個(gè)寫啦O(∩_∩)O~
1. 返回ResponseBody
Retrofit retrofit = new Retrofit.Builder().baseUrl(Api.baseUrl).build();
Api api = retrofit.create(Api.class);
Call<ResponseBody> call = api.getData();
//開始異步請(qǐng)求
call.enqueue(new Callback<ResponseBody>() {
@Override
public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {
try {
String data = response.body().string();
txt.setText(data);
}
catch (IOException e) {
e.printStackTrace();
}
}
@Override
public void onFailure(Call<ResponseBody> call, Throwable t) {
t.printStackTrace();
}
});
2. 返回解析后的對(duì)象
注意注意:必須創(chuàng)建一個(gè)轉(zhuǎn)換器,才可以哦荞彼,不然會(huì)發(fā)現(xiàn) Unable to create converter for ...的錯(cuò)誤哦
-
添加轉(zhuǎn)換器
- 根據(jù)gson解析工具建立實(shí)體類待笑,不建議使用鸣皂,原因后面說~
public class ResultBean {
...
private int id;
...
}
3.開始使用
把responseBody改成ResultBean,然后加上converter轉(zhuǎn)換器就好
@GET("goods/tags/goods/1?g_id=0")
Call<ResultBean> getObjectBean();
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(baseUrl)
.addConverterFactory(GsonConverterFactory.create())
.build();
Api api = retrofit.create(Api.class);//接口對(duì)象
Call<ResultBean> call = api.getObjectBean();
//開始異步請(qǐng)求
call.enqueue(new Callback<ResultBean>() {
@Override
public void onResponse(Call<ResultBean> call, Response<ResultBean> response) {
ResultBean resultBean = response.body();
txt.setText(resultBean.getData().toString());
}
@Override
public void onFailure(Call<ResultBean> call, Throwable t) {
t.printStackTrace();
}
});
有沒有人出錯(cuò)的?
尷尬了寞缝,為什么呢仰泻?因?yàn)間son解析錯(cuò)誤,主要是因?yàn)榉?wù)器返回的數(shù)據(jù)應(yīng)該是array:[],但是返回成了這樣子的array:null慎宾,所以說浅悉,為了防止這種問題,就最好是使用responseBody,然后自己解析
三术健、動(dòng)態(tài)參數(shù)接口GET請(qǐng)求
- 接口的最終樣式是goods/tags/goods/1?g_id=0,這里我們將g_id的值動(dòng)態(tài)改變
@GET("goods/tags/goods/1")
Call<ResponseBody> getGoodsData(@Query("g_id") int id);
...
Call<ResponseBody> call = api.getGoodsData(0);
...
- 將1?g_id=0都動(dòng)態(tài)改變
@GET("goods/tags/goods/{page}")
Call<ResponseBody> getGoodsDataInfo(@Path("page") int page, @Query("g_id") int id);
Call<ResponseBody> call = api.getGoodsDataInfo(1,0);
- 動(dòng)態(tài)添加不確定數(shù)量的參數(shù)和類型
@GET("goods/tags/goods/{page}")
Call<ResponseBody> getGoodsDataParams(@Path("page") int page,@QueryMap Map<String,Integer> params);
HashMap<String, Integer> hash = new HashMap<>();
hash.put("page",1);
hash.put("g_id", 0);
Call<ResponseBody> call = api.getGoodsDataParams(1, hash);
- 傳數(shù)組
@GET("v1/enterprise/find")
Call<ResponseBody> getData(@Query("id") String id, @Query("linked[]") String... linked);
四荞估、Post請(qǐng)求
由于沒有接口,只能這樣子啦
- Post表單提交
@FormUrlEncoded
@POST("user/edit")
Call<Result> editUser(@Field("id") int id, @Field("name") String name);
如果報(bào)了@Field parameters can only be used with form encoding這個(gè)錯(cuò)誤跪腹,則需要使用 @FormUrlEncoded
api.editUser(1, "liuguilin").enqueue(new Callback<Result>() {
@Override
public void onResponse(Call<Result> call, Response<Result> response) {
if (response.body().getYes() == 0) {
Toast.makeText(MainActivity.this, "成功", Toast.LENGTH_SHORT).show();
}
}
@Override
public void onFailure(Call<Result> call, Throwable t) {
}
});
- Post傳json格式
{
data:""
}
public class DataBean {
private String data;
...
}
@POST("user/data")
Call<ResponseBody> getData(@Body DataBean data);
- Post傳文件-單個(gè)
@Multipart
@POST("file/create")
Call<ResponseBody> create(@Part("pictureName") RequestBody pictureName, @Part MultipartBody.Part picture);
RequestBody pictureNameBody = RequestBody.create(MediaType.parse(AppConstants.CONTENT_TYPE_FILE), "pictureName");
File picture= new File(path);
RequestBody requestFile = RequestBody.create(MediaType.parse(AppConstants.CONTENT_TYPE_FILE), picture);
// MultipartBody.Part is used to send also the actual file name
MultipartBody.Part picturePart = MultipartBody.Part.createFormData("picture", picture.getName(), requestFile);
//調(diào)接口
create(pictureNameBody, picturePart);
- Post傳文件-多個(gè)
@Multipart
@POST("files/create")
Call<ResponseBody> create(@Part("pictureName") RequestBody pictureName, @PartMap Map<String, RequestBody> params);
RequestBody pictureNameBody = RequestBody.create(MediaType.parse(AppConstants.CONTENT_TYPE_FILE), "pictureName");
File picture= new File(path);
RequestBody requestFile = RequestBody.create(MediaType.parse(AppConstants.CONTENT_TYPE_FILE), picture);
Map<String, RequestBody> params = new HashMap<>();
params.put("picture\"; filename=\"" + picture.getName() + "", requestFile);
//調(diào)接口
create(pictureNameBody, params);
五冲茸、添加Header
@Headers("Cache-Control: max-age=640000")
@GET("widget/list")
Call<List<Widget>> widgetList();
六轴术、log信息攔截
compile 'com.squareup.okhttp3:logging-interceptor:3.6.0'
OkHttpClient.Builder builder = new OkHttpClient.Builder();
if (BuildConfig.DEBUG) {
HttpLoggingInterceptor httpLoggingInterceptor = new HttpLoggingInterceptor();
httpLoggingInterceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
builder.addInterceptor(httpLoggingInterceptor);
}
七钦无、完整配置
OkHttpClient.Builder builder = new OkHttpClient.Builder();
if (BuildConfig.DEBUG) {
HttpLoggingInterceptor httpLoggingInterceptor = new HttpLoggingInterceptor();
httpLoggingInterceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
builder.addInterceptor(httpLoggingInterceptor);
}
initCache(builder);
initParameter(builder);
initTimeOut(builder);
//將這些配置設(shè)置給retrofit
OkHttpClient client = builder.build();
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(baseUrl)
.addConverterFactory(GsonConverterFactory.create())
.client(client)
.build();
Api api = retrofit.create(Api.class);//創(chuàng)建接口對(duì)象
//設(shè)置超時(shí)和重連
private void initTimeOut(OkHttpClient.Builder builder) {
//設(shè)置超時(shí)
builder.connectTimeout(15, TimeUnit.SECONDS);
builder.readTimeout(20, TimeUnit.SECONDS);
builder.writeTimeout(20, TimeUnit.SECONDS);
//錯(cuò)誤重連
builder.retryOnConnectionFailure(true);
}
//添加公共參數(shù)
private void initParameter(OkHttpClient.Builder builder) {
Interceptor parameterInterceptor = new Interceptor() {
@Override
public okhttp3.Response intercept(Chain chain) throws IOException {
Request originalRequest = chain.request();
Request request;
String method = originalRequest.method();
Headers headers = originalRequest.headers();
HttpUrl modifiedUrl = originalRequest.url().newBuilder()
.addQueryParameter("platform", "android")
.addQueryParameter("version", "1.0.0")
.build();
request = originalRequest.newBuilder().url(modifiedUrl).build();
return chain.proceed(request);
}
};
builder.addInterceptor(parameterInterceptor);
}
//設(shè)置緩存失暂,無網(wǎng)絡(luò)時(shí)鳄虱,也能顯示數(shù)據(jù)
private void initCache(OkHttpClient.Builder builder) {
File cacheFile = new File(this.getExternalCacheDir(), "cache");
Cache cache = new Cache(cacheFile, 1024 * 1024 * 50);//緩存文件50M
Interceptor interceptor = new Interceptor() {
@Override
public okhttp3.Response intercept(Chain chain) throws IOException {
Request request = chain.request();
if (!netWorkIsAvailable) {//網(wǎng)絡(luò)不可用
request = request.newBuilder().cacheControl(CacheControl.FORCE_CACHE).build();
}
else {//網(wǎng)絡(luò)可用
request = request.newBuilder()
.cacheControl(CacheControl.FORCE_NETWORK)
.build();
}
okhttp3.Response response = chain.proceed(request);
if (netWorkIsAvailable) {
int maxAge = 0;
response.newBuilder()
.header("Cache-Control", "public, max-age=" + maxAge)//覆蓋服務(wù)器響應(yīng)頭的Cache-Control,用我們自己的,因?yàn)榉?wù)器響應(yīng)回來的可能不支持緩存
.removeHeader("Pragma")//清除頭信息醇蝴,因?yàn)榉?wù)器如果不支持想罕,會(huì)返回一些干擾信息霉涨,不清無法生效
.build();
}
else {
int maxStale = 60 * 60 * 24 * 28;//無網(wǎng)絡(luò)時(shí),設(shè)置超時(shí)為4周
response.newBuilder()
.header("Cache-Control", "public, only-if-cached, max-stale=" + maxStale)
.removeHeader("Pragma")
.build();
}
return response;
}
};
builder.cache(cache).addInterceptor(interceptor);
}
八楼镐、移除請(qǐng)求
call.cancel();
后記
Github:https://github.com/square/retrofit
官網(wǎng)文檔:http://square.github.io/retrofit/
參考網(wǎng)址
Retrofit2.0通俗易懂的學(xué)習(xí)姿勢(shì)往枷,Retrofit2.0 + OkHttp3 + Gson + RxJava
Android Retrofit 2.0 使用-補(bǔ)充篇
Retrofit中如何正確的使用https?