此篇文章主要記錄下自己使用Retrofit后簡(jiǎn)易的封裝软吐,和相對(duì)全面的請(qǐng)求類型的注解使用方法,也是對(duì)知識(shí)點(diǎn)的一個(gè)總結(jié)和復(fù)習(xí)。
Retrofit是什么衩椒?
簡(jiǎn)單來(lái)說(shuō)Retrofit是一個(gè)網(wǎng)絡(luò)請(qǐng)求框架,基于OkHttp做了進(jìn)一步封裝哮兰,更好的適用于RESTful URL格式風(fēng)格毛萌,通過(guò)注解配置參數(shù),可以靈活的設(shè)置URL喝滞、請(qǐng)求頭阁将、請(qǐng)求體等。
優(yōu)點(diǎn)
- 超級(jí)解耦
- 處理速度快
- 使用靈活方便
- 可以使用注解控制請(qǐng)求的參數(shù)
封裝
public class RetrofitManager {
private static RetrofitManager mRetrofitManager;
private Retrofit mRetrofit;
private static Context mContext;
public RetrofitManager(Context context) {
this.mContext = context;
initRetrofit();
}
public static synchronized RetrofitManager getInstance(){
if (mRetrofitManager == null){ mRetrofitManager = new RetrofitManager(mContext);}
return mRetrofitManager;
}
private void initRetrofit(){
OkHttpClient.Builder builder = new OkHttpClient.Builder();
//添加攔截器
builder.addInterceptor(new ResponseInterceptor ());
builder.addInterceptor(new RequestInterceptor ());
OkHttpClient client = builder
//設(shè)置請(qǐng)求超時(shí)時(shí)間
.connectTimeout(30, TimeUnit.SECONDS)
.readTimeout(30, TimeUnit.SECONDS)
.writeTimeout(30, TimeUnit.SECONDS)
.build();
mRetrofit = new Retrofit.Builder()
.baseUrl(AlderApiService.BASE_URL)
// addConverterFactory 對(duì)服務(wù)器數(shù)據(jù)進(jìn)行解析
.addConverterFactory(GsonConverterFactory.create())//利用Gson解析返回的json
.addConverterFactory(ScalarsConverterFactory.create())
.client(client)
.build();
}
public <T> T createReq(Class<T> reqServer){
return mRetrofit.create(reqServer);
}
}
一般使用時(shí)只用調(diào)用這個(gè)類就行了右遭,這里主要添加了請(qǐng)求的攔截器做盅、設(shè)置請(qǐng)求的超時(shí)時(shí)間疚脐、對(duì)添加請(qǐng)求的base url阅茶、添加對(duì)服務(wù)器返回?cái)?shù)據(jù)的解析。
攔截器
public class ResponseInterceptor implements Interceptor {
private final String TAG = "ResponseInterceptor ";
@Override
public Response intercept(Chain chain) throws IOException {
Response response = chain.proceed(chain.request());
if(response!= null){
if ( response.header("token") != null ){
//獲取請(qǐng)求頭中的token 并保存在sp中
final String token = response.header("token");
SharedPreferencesUtils.getInstance().putString(SharedPreferencesUtils.TOKEN,token);
Log.e(TAG,"保存在本地的token為:"+token);
}
}
return response;
}
}
獲取Response的請(qǐng)求頭內(nèi)容畏吓,項(xiàng)目里只用到了token滚婉,所以這里只獲取了token進(jìn)行保存图筹。
public class RequestInterceptor implements Interceptor {
}
} private final String TAG = "RequestInterceptor ";
@Override
public Response intercept(Chain chain) throws IOException {
final Request.Builder builder = chain.request().newBuilder();
String token = SharedPreferencesUtils.getInstance().getString(SharedPreferencesUtils.TOKEN,"");
if (!token.isEmpty()&& null!=token&& !"".equals(token)){
//添加請(qǐng)求頭,攜帶token
builder.addHeader("token",token);
Log.i(TAG,"攜帶的本地token為:"+token);
}
return chain.proceed(builder.build());
給Request請(qǐng)求頭中添加token。
Retrofit Service
我是主要在這里管理各個(gè)請(qǐng)求和base url满哪,貼個(gè)圖婿斥,大概格式就是這樣
封裝好后該如何使用劝篷?
簡(jiǎn)單粗暴上代碼
public void registerSubmit(String name,String pwd,String email){
mIRegisterView.showSubmitWaitDialog();
RetrofitManager retrofitManager = new RetrofitManager(mContext);
AlderApiService.RegisterService registerService = retrofitManager.createReq(AlderApiService.RegisterService.class);
Call<Result> requestBodyCall = registerService.register(name,pwd,email);
requestBodyCall.enqueue(new Callback<Result>() {
@Override
public void onResponse(Call<Result> call, Response<Result> response) {
mIRegisterView.dismissSubmitWaitDialog();
Result result = response.body();
Log.i(TAG,"result : "+result.toString());
if(response.body() != null){
if (result.isResult()){
//success
}else {
//fail
}
}else {
mIRegisterView.OnRegisterFailed(ErrorCode.REQUEST_BODY_ERROR);
}
}
@Override
public void onFailure(Call<Result> call, Throwable t) {
mIRegisterView.dismissSubmitWaitDialog();
mIRegisterView.OnRegisterFailed(ErrorCode.NETWORK_ERROR);
}
});
}
注解的使用
下面列舉的不是全部的注解,只是列舉了在不同請(qǐng)求中遇到過(guò)使用過(guò)的注解民宿。
POST請(qǐng)求
1. 普通的表單格式提交
@FormUrlEncoded 表單格式
@POST post請(qǐng)求方式
@Field 表單提交參數(shù)
一般這三個(gè)注解會(huì)一起使用娇妓,例如:
@FormUrlEncoded
@POST("v1/user/login")
Call<Result> login(@Field("userName") String userName);
這里@Field 中的userName是接口中定義的參數(shù)名,后面的userName是本地調(diào)用時(shí)傳的參數(shù)
2. 提交json格式
@Headers 添加請(qǐng)求頭
@Body 請(qǐng)求攜帶的參數(shù)(對(duì)象類型)
這里添加請(qǐng)求頭和我們前面在攔截器中添加都可以活鹰,因?yàn)檫@個(gè)請(qǐng)求方式是極少數(shù)哈恰,所以只是在這里單獨(dú)添加,內(nèi)容類型為json
@Headers({"Content-Type:application/json","Accept: application/json"})
@POST("v1/user/remove")
Call<Result> deleteUser(@Body RequestBody requestBody);
@Body 就是傳入的參數(shù)為RequestBody類型
這個(gè)方法調(diào)用時(shí)傳入的參數(shù)為這樣
RequestBody body=RequestBody.create(okhttp3.MediaType.parse("application/json; charset=utf-8"),json.toString());
一般這種提交是用在批量刪除的時(shí)候志群,將id集合以json的形式提交着绷。
3. 路徑中攜帶參數(shù)
@Path 將參數(shù)放在路徑中
@FormUrlEncoded
@POST("v1/panel/{imei}")
Call<Result<Integer>> armControl(@Path("imei") String imei,@Field("armingLevel") int armingLeve);
@Path 有一些提交的參數(shù)是明文提交,也就是直接在url路徑中顯示的锌云,這時(shí)用到的注解就是TA
GET請(qǐng)求
1. 普通get
@GET get請(qǐng)求方式
@GET("v1/user/info")
Call<Result<AccountInformation>> getAccount();
@GET 這個(gè)注解就不用做過(guò)多解釋了荠医,和post為兩種請(qǐng)求方式
2. 帶參get請(qǐng)求①
@GET("v1/camera/{deviceID}")
Call<GetCamera> getCameraInfo(@Path("deviceID") Integer deviceID);
這里有用到@Path,用法其實(shí)是一樣的桑涎,在url中攜帶參數(shù)彬向。
3. 帶參get請(qǐng)求②
@Query 請(qǐng)求攜帶參數(shù)
@QueryMap 請(qǐng)求攜帶參數(shù)集合
@GET("v1/notification")
Call<Result<Map<String,List<Notification>>>> getNotification(@Query("cameraId") String cameraId);
@Query 在一定意義上和@Path是差不多的,最終的參數(shù)都是在請(qǐng)求的url中攻冷,@Query 是不需要我們自己在url中寫參數(shù)的key娃胆,url最終的效果是v1/notification?cameraId=xxx,用上面的栗子來(lái)看的話 @Path url最終的效果是v1/camera/xx
DELETE請(qǐng)求
@DELETE 刪除
@DELETE("rest/{deviceID}")
Call<String> deleteCamera(@Path("deviceID") String deviceID);
一般這樣的操作等曼,在后臺(tái)提供的接口時(shí)也需要使用RESTful風(fēng)格中的@DELETE來(lái)匹配
目前在項(xiàng)目中常用的一些注解和封裝方法就醬紫啦里烦,寫的比較基礎(chǔ),也沒(méi)有實(shí)在性的技術(shù)語(yǔ)言去講解禁谦,但把如何使用的例子都貼的很清楚胁黑,我覺(jué)得有些東西能說(shuō)出來(lái)并不一定會(huì)用,但是當(dāng)你會(huì)用了就一定能說(shuō)州泊,不應(yīng)該把對(duì)技術(shù)的學(xué)習(xí)停留在理論上 -.而且對(duì)于菜鳥的我來(lái)說(shuō)别厘,在網(wǎng)上查到的一些結(jié)束貼,大部分都是文字說(shuō)明文字說(shuō)明文字說(shuō)明....看的到最后頭大了都不知道該怎么去用拥诡,把怎么用講清楚最實(shí)在触趴。
還有很多注解沒(méi)有寫到,等以后用了再繼續(xù)補(bǔ)充~~
希望在技術(shù)的路上越走越好~~