retrofit基於okhttp封裝的網絡請求框架,網絡請求的工做本質上是 OkHttp 完成,而 retrofit 僅負責網絡請求接口的封裝.若是你不瞭解OKhttp建議你仍是先了解它在來學習使用retrofit,傳送門:Android 開發 框架系列 OkHttp使用詳解html
Retrofit優點,就是簡潔易用,解耦,擴展性強,可搭配多種Json解析框架(例如Gson),另外還支持RxJava.可是,這篇博客不講解RxJava配合使用的部分,與RxJava的配合使用將在另一篇博客中講解.git
另外retrofit已是封裝的很是好了,已經最大程度上的匹配各類使用狀況,因此不建議畫蛇添足的再次封裝retrofit(最多封裝retrofit的單例). 再次封裝不會看起來很帥也不會讓你很牛逼. 只會讓你看起來更蠢.把已經很拓展很解耦的實現所有破壞.github
https://github.com/square/retrofitjson
若是你不須要使用RxJava模式,那麼你只須要依賴下面2個:服務器
implementation 'com.squareup.retrofit2:retrofit:2.6.2' implementation 'com.squareup.retrofit2:converter-gson:2.4.0'
gson是用來解析的Json數據使用的(我的偏心Gson),retrofit也支持其餘解析工具好比fastJson網絡
老規矩按思惟順序講解demoapp
Retrofit配置好後,能夠全局使用這一個Retrofit用來請求網絡(因此你能夠實現單例以全局使用),固然下面的代碼只是demo:框架
private Retrofit mRetrofit; private void initHttpBase(){ mRetrofit = new Retrofit.Builder() .baseUrl("http://doclever.cn:8090/mock/5c3c6da33dce46264b24452b/")//base的網絡地址 baseUrl不能爲空,且強制要求必需以 / 斜槓結尾 .addConverterFactory(GsonConverterFactory.create())//使用Gson解析 .callbackExecutor(Executors.newSingleThreadExecutor())//使用單獨的線程處理 (這很重要,通常網絡請求若是不設置可能不會報錯,可是若是是下載文件就會報錯) .build(); }
注意! base的網絡地址 baseUrl不能爲空,且強制要求必需以 / 斜槓結尾異步
public class LoginBean { private int code; private String message; public int getCode() { return code; } public void setCode(int code) { this.code = code; } public String getMessage() { return message; } public void setMessage(String message) { this.message = message; } }
public interface HttpList { @FormUrlEncoded //註解表示from表單 還有@Multipart 表單可供使用 固然你也能夠不添加 @POST("test/login_test") //網絡請求路徑 Call<LoginBean> login(@Field("number") String number, @Field("password") String password); //@Field("number") 爲post值的的key }
注意,這是一個接口類. LoginBean則是數據返回後的Bean類(Retrofit會自動使用導入的Gson解析)ide
注意! @POST("test/login_test") 這路徑最前面不能加斜槓 / ,不然它會自動裁剪路徑,這樣會致使你的路徑錯誤
private void postHttp(){ HttpList httpList = mRetrofit.create(HttpList.class); Call<LoginBean> call = httpList.login("181234123", "123456"); call.enqueue(new Callback<LoginBean>() { @Override public void onResponse(Call<LoginBean> call, Response<LoginBean> response) { LoginBean bean = response.body(); Log.e(TAG, "onResponse: code="+bean.getCode()); Log.e(TAG, "onResponse: message="+bean.getMessage()); } @Override public void onFailure(Call<LoginBean> call, Throwable t) { Log.e(TAG, "onFailure: 網絡請求失敗="+t.getMessage()); } }); }
這樣,咱們就完成了一個網絡請求.是否是特別簡單
private void postHttp2() { HttpList httpList = mRetrofit.create(HttpList.class); final Call<LoginBean> call = httpList.login("181234123", "123456"); new Thread(new Runnable() { //Android主線程不能操做網絡請求,因此new一個線程來操做 @Override public void run() { try { Response<LoginBean> response = call.execute();//同步請求網絡 LoginBean bean = response.body(); Log.e(TAG, "onResponse: code=" + bean.getCode()); Log.e(TAG, "onResponse: message=" + bean.getMessage()); } catch (IOException e) { e.printStackTrace(); } } }).start(); }
public void cancelHttp(){ HttpList httpList = mRetrofit.create(HttpList.class); //這裏貼這部分代碼是告訴call是哪裏來的,關鍵點就是這個call,固然你也能夠從回調裏獲取 mCall = httpList.login("181234123", "123456"); mCall.cancel(); //取消請求 }
以固定數據的形式添加頭信息
public interface HttpList { @Headers({"content1:one","content2:two"}) @POST("test/logout_test") Call<LoginBean> logout1(); }
以非固定數據的形式添加頭信息
public interface HttpList { @POST("test/logout_test") Call<LoginBean> logout2(@Header("content") String content); }
Body通常有4個種類
框架直接提供的2個Body
public interface HttpList { @FormUrlEncoded //application/x-www-form-urlencoded 表單body @POST("test/login_test") Call<LoginBean> login2(@Field("number") String number, @Field("password") String password); @Multipart //multipart/form-data 此body支持文件上傳與下載 @POST("test/login_test") Call<LoginBean> login3(@Field("number") String number, @Field("password") String password); }
其餘2個就須要自定義建立了,下面舉例Json Body的建立:
/** * * @param string 直接導入須要發送給服務器的JSON的String值 * @return */ public static RequestBody getRequestBody(String string) { return RequestBody.create(MediaType.parse("application/json; charset=utf-8"), string); }
在接口類參數須要設置爲 @Body RequestBody requestBody
@POST("app/system/demo")
Observable<UpdateInfo> demo(@Body RequestBody requestBody);
上面說了retrofit是基於Okhttp開發的網絡請求框架,因此它有一部分的功能依然須要使用Okhttp的方式來配置好比請求超時時間/設置攔截器等等,下面就展現一下如何添加
private void initHttpBase2() { OkHttpClient okHttpClient = new OkHttpClient.Builder() .retryOnConnectionFailure(false) //在鏈接失敗時重試 .callTimeout(30, TimeUnit.SECONDS) //呼叫超時,設置此參數爲總體流程請求的超時時間 .connectTimeout(20,TimeUnit.SECONDS)//鏈接超時 .readTimeout(20,TimeUnit.SECONDS)//讀取超時 .writeTimeout(20,TimeUnit.SECONDS)//寫入超時 // .callTimeout()//呼叫超時,設置此參數爲總體流程請求的超時時間 // .addInterceptor() //設置攔截器 // .authenticator() //設置認證器 // .proxy()//設置代理 .build(); mRetrofit = new Retrofit.Builder() .client(okHttpClient) .baseUrl("http://doclever.cn:8090/mock/5c3c6da33dce46264b24452b/")//base的網絡地址 .addConverterFactory(GsonConverterFactory.create())//使用Gson解析 .callbackExecutor(Executors.newSingleThreadExecutor()) .build(); }
@POST("/article/query/{page}/json") @FormUrlEncoded Observable<DataResponse<Article>> getSearchArticles(@Path("page") int page, @Field("k") String k);
end