retrofit學(xué)習(xí)

前言

Retrofit是一個(gè)網(wǎng)絡(luò)請(qǐng)求李丰,用法簡(jiǎn)潔方便,一起來學(xué)習(xí)一下吧O(∩_∩)O~

一、配置

工具是 Android Studio罢荡,所以這里只講AndroidStudio的配置
**1. build.gradle **
首先紧索,如圖添加retrofit和okhttp


Paste_Image.png
    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();
          }
      });
結(jié)果

2. 返回解析后的對(duì)象
注意注意:必須創(chuàng)建一個(gè)轉(zhuǎn)換器,才可以哦荞彼,不然會(huì)發(fā)現(xiàn) Unable to create converter for ...的錯(cuò)誤哦

  1. 添加轉(zhuǎn)換器


    compile 'com.squareup.retrofit2:converter-gson:2.2.0'
  2. 根據(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)求

  1. 接口的最終樣式是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. 將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);
  1. 動(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);
  1. 傳數(shù)組
@GET("v1/enterprise/find")
Call<ResponseBody> getData(@Query("id") String id, @Query("linked[]") String... linked);

四荞估、Post請(qǐng)求

由于沒有接口,只能這樣子啦

  1. 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) {

     }
 });
  1. Post傳json格式
{
 data:""
}
public class DataBean {
    private String data;
      ...
}
@POST("user/data")
Call<ResponseBody> getData(@Body DataBean data);
  1. 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);
  1. 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?

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末秉宿,一起剝皮案震驚了整個(gè)濱河市描睦,隨后出現(xiàn)的幾起案子导而,更是在濱河造成了極大的恐慌,老刑警劉巖今艺,帶你破解...
    沈念sama閱讀 206,602評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件虚缎,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡千康,警方通過查閱死者的電腦和手機(jī)铲掐,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,442評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來豪椿,“玉大人,你說我怎么就攤上這事搭盾。” “怎么了澜建?”我有些...
    開封第一講書人閱讀 152,878評(píng)論 0 344
  • 文/不壞的土叔 我叫張陵炕舵,是天一觀的道長(zhǎng)跟畅。 經(jīng)常有香客問我,道長(zhǎng)徊件,這世上最難降的妖魔是什么虱痕? 我笑而不...
    開封第一講書人閱讀 55,306評(píng)論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮疏橄,結(jié)果婚禮上略就,老公的妹妹穿的比我還像新娘。我一直安慰自己表牢,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,330評(píng)論 5 373
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著敲茄,像睡著了一般。 火紅的嫁衣襯著肌膚如雪掏父。 梳的紋絲不亂的頭發(fā)上秆剪,一...
    開封第一講書人閱讀 49,071評(píng)論 1 285
  • 那天爵政,我揣著相機(jī)與錄音陶缺,去河邊找鬼。 笑死掺出,一個(gè)胖子當(dāng)著我的面吹牛伶贰,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 38,382評(píng)論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼琅翻,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼柑贞!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起棠众,我...
    開封第一講書人閱讀 37,006評(píng)論 0 259
  • 序言:老撾萬榮一對(duì)情侶失蹤有决,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后新荤,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體台汇,經(jīng)...
    沈念sama閱讀 43,512評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,965評(píng)論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了牵素。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,094評(píng)論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡瞳步,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出抱怔,到底是詐尸還是另有隱情嘀倒,我是刑警寧澤,帶...
    沈念sama閱讀 33,732評(píng)論 4 323
  • 正文 年R本政府宣布灌危,位于F島的核電站碳胳,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏挨约。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,283評(píng)論 3 307
  • 文/蒙蒙 一翁锡、第九天 我趴在偏房一處隱蔽的房頂上張望馆衔。 院中可真熱鬧怨绣,春花似錦、人聲如沸梨熙。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,286評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽质欲。三九已至,卻和暖如春怎憋,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背绊袋。 一陣腳步聲響...
    開封第一講書人閱讀 31,512評(píng)論 1 262
  • 我被黑心中介騙來泰國(guó)打工癌别, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人躁垛。 一個(gè)月前我還...
    沈念sama閱讀 45,536評(píng)論 2 354
  • 正文 我出身青樓圾笨,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親土铺。 傳聞我的和親對(duì)象是個(gè)殘疾皇子板鬓,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,828評(píng)論 2 345

推薦閱讀更多精彩內(nèi)容

  • 寫在前面## 其實(shí)一直都沒有寫博客的習(xí)慣,借著這次公司內(nèi)部分享的機(jī)會(huì),開始寫博客丁溅,希望以后漸漸養(yǎng)成習(xí)慣窟赏。也方便以后...
    seph_von閱讀 875評(píng)論 0 1
  • Android 自定義View的各種姿勢(shì)1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 171,510評(píng)論 25 707
  • 簡(jiǎn)介 剛接觸Retrofit的時(shí)候涯穷,就寫了一篇簡(jiǎn)單的使用介紹:Retrofit 2.0基本使用方法,算是對(duì)Retr...
    Whyn閱讀 2,836評(píng)論 4 24
  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn)作煌,斷路器赚瘦,智...
    卡卡羅2017閱讀 134,599評(píng)論 18 139
  • 《想你,是我給這片天空的承諾》 我習(xí)慣了失去雙手去觸摸每一個(gè)模糊的輪廓鹰服, 只有用眼睛一遍又一遍翻著深刻的相冊(cè)。 我...
    野心要優(yōu)雅哦閱讀 112評(píng)論 0 0