Android開發 retrofit入門講解

前言

  retrofit基於okhttp封裝的網絡請求框架,網絡請求的工做本質上是 OkHttp 完成,而 retrofit 僅負責網絡請求接口的封裝.若是你不瞭解OKhttp建議你仍是先了解它在來學習使用retrofit,傳送門:Android 開發 框架系列 OkHttp使用詳解html

  Retrofit優點,就是簡潔易用,解耦,擴展性強,可搭配多種Json解析框架(例如Gson),另外還支持RxJava.可是,這篇博客不講解RxJava配合使用的部分,與RxJava的配合使用將在另一篇博客中講解.git

  另外retrofit已是封裝的很是好了,已經最大程度上的匹配各類使用狀況,因此不建議畫蛇添足的再次封裝retrofit(最多封裝retrofit的單例). 再次封裝不會看起來很帥也不會讓你很牛逼. 只會讓你看起來更蠢.把已經很拓展很解耦的實現所有破壞.github

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網絡

簡單的Demo(異步請求)

  老規矩按思惟順序講解demoapp

1.建立Retrofit請求基礎配置

  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不能爲空,且強制要求必需以 / 斜槓結尾異步

2.建立數據返回後的Bean類

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;
    }
}

2.建立一個網絡請求接口

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") 這路徑最前面不能加斜槓 /  ,不然它會自動裁剪路徑,這樣會致使你的路徑錯誤

3.請求網絡

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(); //取消請求
    }

如何添加Header頭

以固定數據的形式添加頭信息

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配置

Body通常有4個種類

  • application/x-www-form-urlencoded 表單數據
  • multipart/form-data 表單文件上傳
  • application/json 序列化JSON數據
  • text/xml XML數據

框架直接提供的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);


}

自定義Body

其餘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);

添加配置的OkHttpClient(主要使用請求超時/攔截器等功能)

上面說了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();
    }

 部分路徑動態的BaseUrl

    @POST("/article/query/{page}/json")
    @FormUrlEncoded
    Observable<DataResponse<Article>> getSearchArticles(@Path("page") int page, @Field("k") String k);

 

 

end

相關文章
相關標籤/搜索