Android - 網(wǎng)絡(luò)請(qǐng)求之 Retrofit2 + RxJava

老婆保佑植捎,代碼無BUG

目錄

  • 引用
  • 與其他開源請(qǐng)求庫對(duì)比
  • Retrofit注解
  • 使用
    • GET請(qǐng)求
    • POST請(qǐng)求
  • Retrofit2 + RxJava
    • 基礎(chǔ)使用
    • 優(yōu)化
    • 封裝Retrofit2 + RxJava

一:引用

retrofit 官網(wǎng)

compile 'com.squareup.retrofit2:retrofit:2.3.0'

二:與其他開源請(qǐng)求庫對(duì)比

image

三:Retrofit注解

四:使用

GET請(qǐng)求

(1) 定義接口


public interface ApiService {
    @GET
    Call<ResponseBody> getGetData(@Url String url);
    
    //Get請(qǐng)求,方法中指定@Path參數(shù)和@Query參數(shù)
    //@path參數(shù)用于替換url中{}的部分宙刘,
    //@Query將在url地址中追加類似"page=1"的字符串
    @GET("{mobile}/get?") 
    Call<ResponseBody> getPathData(@Path("mobile") String mobile, @Query("phone") String phone, @Query("key") String key);

    @GET("mobile/get?")
    Call<ResponseBody> getQueryMapData(@QueryMap Map<String, String> map);

}

(2) Activity

    public void btnYS(View view) {
        String baseUrl = "http://apis.juhe.cn/";
        String url = baseUrl + "mobile/get?phone=18856907654&key=5778e9d9cf089fc3b093b162036fc0e1";
        Retrofit retrofit = new Retrofit.Builder()
                .baseUrl(baseUrl)
                .build();
        ApiService apiService = retrofit.create(ApiService.class);
        
        //第一種
        Call<ResponseBody> call = apiService.getGetData(url);
        
        //第二種
        HashMap<String, String> map = new HashMap<>();
        map.put("phone", "18856907654");
        map.put("key", "5778e9d9cf089fc3b093b162036fc0e1");
        Call<ResponseBody> call = apiService.getQueryMapData(map);
        
        //第三種
        apiService.getPathData("mobile","18856907654","5778e9d9cf089fc3b093b162036fc0e1");
        
        
        
        call.enqueue(new Callback<ResponseBody>() {
            @Override
            public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {
                //主線程
                try {
                    Logger.e("response---->" + response.body().string());
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }

            @Override
            public void onFailure(Call<ResponseBody> call, Throwable t) {
                Logger.e("Throwable---->" + t.getMessage());
            }
        });
    }

POST請(qǐng)求

(1) 定義接口

public interface ApiService {
    @FormUrlEncoded
    @POST("mobile/get")  //注意  不是 /  結(jié)束
    Call<ResponseBody> postFile(@Field("phone") String phone,
                                @Field("key") String key);
                                
    @FormUrlEncoded
    @POST("mobile/get")  //注意  不是 /  結(jié)束
    Call<ResponseBody> postFile(@FieldMap Map<String,String> map);
}

(2) Activity

    public void btnPostFile(View view) {
        String baseUrl = "http://apis.juhe.cn/";
        Retrofit retrofit = new Retrofit.Builder()
                .baseUrl(baseUrl)
                .build();
        ApiService apiService = retrofit.create(ApiService.class);
        
        //第一種
        Call<ResponseBody> call = apiService.postFile("18856907654", "5778e9d9cf089fc3b093b162036fc0e1");
        
        //第二種
        HashMap<String, String> map = new HashMap<>();
        map.put("phone", "18856907654");
        map.put("key", "5778e9d9cf089fc3b093b162036fc0e1");
        Call<ResponseBody> call = apiService.postFile(map);
         //省略一下代碼
    }

以上講的都是廢話锄贷,哈哈下面才是正確的打開放式


Retrofit2 + RxJava

引入 依賴

//Retrofit2
compile 'com.squareup.retrofit2:retrofit:2.3.0'
//RxJava
compile 'io.reactivex.rxjava2:rxjava:2.1.7'
//RxAndroid
compile 'io.reactivex.rxjava2:rxandroid:2.0.1'
//Retrofit 支持Rxjava 的支持庫
compile 'com.jakewharton.retrofit:retrofit2-rxjava2-adapter:1.0.0'

先導(dǎo)入译蒂,然后慢慢說,這些都是干啥的

按套路出牌谊却,肯定先寫接口

public interface ApiService {
    @GET
    Observable<ResponseBody> getGetData(@Url String url);
}

看到這柔昼,就有兄弟說了,哥們你這里寫錯(cuò)了炎辨,不應(yīng)該是Observable應(yīng)該是Call

u=1804519813,2654766997&fm=27&gp=0.jpg

都說了 之前說的都是屁話捕透,這才是正確的打開方式,我們使用的是Observable碴萧,RxJava 乙嘀,都是這么玩的 哈哈

so 繼續(xù)

Activity 先來一個(gè)看看

package com.allens.retrofitdemo;

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;

import com.jakewharton.retrofit2.adapter.rxjava2.RxJava2CallAdapterFactory;

import io.reactivex.Observer;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.disposables.Disposable;
import io.reactivex.functions.Consumer;
import io.reactivex.schedulers.Schedulers;
import okhttp3.ResponseBody;
import retrofit2.Retrofit;

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        String baseUrl = "http://apis.juhe.cn/";
        String url = baseUrl + "mobile/get?phone=18856907654&key=5778e9d9cf089fc3b093b162036fc0e1";


        // 設(shè)置網(wǎng)絡(luò)請(qǐng)求的Url地址
        Retrofit retrofit = new Retrofit.Builder()
                .baseUrl("http://fanyi.youdao.com/")
                // 支持RxJava平臺(tái)
                //compile 'com.jakewharton.retrofit:retrofit2-rxjava2-adapter:1.0.0'   是他 就是他 
                .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
                .build();

        retrofit.create(ApiService.class)
                .getGetData(url)//注意看,這里返回的對(duì)象時(shí)什么破喻,和原生的返回不同虎谢,也是我們把上面接口改的原因
                //在子線程取數(shù)據(jù)
                .subscribeOn(Schedulers.io())
                .unsubscribeOn(Schedulers.io())
                //在主線程顯示ui 
                // compile 'io.reactivex.rxjava2:rxandroid:2.0.1'  這個(gè)庫下才有AndroidSchedulers.mainThread
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Observer<ResponseBody>() {
                    @Override
                    public void onSubscribe(Disposable d) {
                        
                    }

                    @Override
                    public void onNext(ResponseBody responseBody) {

                    }

                    @Override
                    public void onError(Throwable e) {

                    }

                    @Override
                    public void onComplete() {

                    }
                });

    }
}

是不是感覺很簡單。哈哈曹质,對(duì)就是這么簡單婴噩。Post 請(qǐng)求也這么玩,其他都不變羽德,改一下接口几莽,改成 Observable,然后使用RxJava 切換線程就哦了,

如果只是這種程度你就滿足了宅静,哈哈章蚣,大兄弟,你也太容易了姨夹,

其實(shí)我們還可以這么玩


五:優(yōu)化

1. 設(shè)置數(shù)據(jù)解析器

(1)添加一條依賴

//gson 解析器
compile 'com.squareup.retrofit2:converter-gson:2.3.0'

修改接口

public interface ApiService {
    @GET
    Observable<Bean> getGetData(@Url String url);
}

找不同纤垂,哈哈 原來的是ResponseBody矾策,現(xiàn)在是Bean,至于Bean 是什么洒忧,Bean 對(duì)象啊,大兄弟够颠,這個(gè)不知道的話熙侍,表示。履磨。蛉抓。。

修改一下Activity中的代碼

Retrofit retrofit = new Retrofit.Builder()
                .baseUrl("http://fanyi.youdao.com/")
                // 設(shè)置數(shù)據(jù)解析器
                .addConverterFactory(GsonConverterFactory.create()) 
                .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
                .build();
retrofit.create(ApiService.class)
                .getGetData(url)
                .subscribeOn(Schedulers.io())
                .unsubscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Observer<Bean>() {
                    @Override
                    public void onSubscribe(Disposable d) {

                    }

                    @Override
                    public void onNext(Bean bean) {

                    }

                    @Override
                    public void onError(Throwable e) {

                    }

                    @Override
                    public void onComplete() {

                    }
                });

可以看到剃诅,原來返回的是ResponseBody,現(xiàn)在返回的是已經(jīng)解析成功的Bean 對(duì)象巷送,

關(guān)于數(shù)據(jù)解析器(Converter)

  • Retrofit支持多種數(shù)據(jù)解析方式
  • 使用時(shí)需要在Gradle添加依賴
數(shù)據(jù)解析器 Gradle依賴
Gson com.squareup.retrofit2:converter-gson:2.0.2
Jackson com.squareup.retrofit2:converter-jackson:2.0.2
Simple XML com.squareup.retrofit2:converter-simplexml:2.0.2
Protobuf com.squareup.retrofit2:converter-protobuf:2.0.2
Moshi com.squareup.retrofit2:converter-moshi:2.0.2
Wire com.squareup.retrofit2:converter-wire:2.0.2
Scalars com.squareup.retrofit2:converter-scalars:2.0.2

網(wǎng)絡(luò)請(qǐng)求適配器(CallAdapter)

還記得compile 'com.jakewharton.retrofit:retrofit2-rxjava2-adapter:1.0.0' 么,他其實(shí)就是一個(gè)網(wǎng)絡(luò)請(qǐng)求適配器
使用時(shí)如使用的是 Android 默認(rèn)的 CallAdapter矛辕,則不需要添加網(wǎng)絡(luò)請(qǐng)求適配器的依賴笑跛,否則則需要按照需求進(jìn)行添加
Retrofit 提供的 CallAdapter
使用時(shí)需要在Gradle添加依賴:

網(wǎng)絡(luò)請(qǐng)求適配器 Gradle依賴 備注
guava com.squareup.retrofit2:adapter-guava:2.0.2 沒用過
Java8 com.squareup.retrofit2:adapter-java8:2.0.2 沒用過
rxjava com.squareup.retrofit2:adapter-rxjava:2.0.2 retrofit現(xiàn)在只支持到rxjava1.XX
rxjava com.jakewharton.retrofit:retrofit2-rxjava2-adapter:1.0. 大神寫的這個(gè)庫可以支持到rxjava2.X

到這里就是不是就感覺,人生圓滿了呢聊品,哈哈
還有后招呢飞蹂,現(xiàn)在我想把服務(wù)端返回的數(shù)據(jù)全部打印出來,怎么做呢

u=1379330171,3486067710&fm=27&gp=0.jpg

2.加入攔截器

(1)導(dǎo)入庫

compile 'com.squareup.okhttp3:logging-interceptor:3.4.1'

(2)初始化HttpLoggingInterceptor

HttpLoggingInterceptor loggingInterceptor = new HttpLoggingInterceptor(new HttpLoggingInterceptor.Logger() {
            @Override
            public void log(String message) {
                //打印retrofit日志
                Log.i("RetrofitLog","retrofitBack = "+message);
            }
        });
        loggingInterceptor.setLevel(HttpLoggingInterceptor.Level.BODY);

(3)配置okhttp

client = new OkHttpClient.Builder()
                    .addInterceptor(loggingInterceptor)
                    .connectTimeout(mTimeOut, TimeUnit.SECONDS)
                    .readTimeout(mTimeOut, TimeUnit.SECONDS)
                    .writeTimeout(mTimeOut, TimeUnit.SECONDS)
                    .build();

然后嘛翻屈,

就可以在控制臺(tái)看到請(qǐng)求的Log啦

12-28 04:29:07.337 3922-3944/com.allens.test E/XRetrofit: retrofitBack -> <-- 200 OK http://devapi.water.com/Oauth/authorize (185ms)
12-28 04:29:07.337 3922-3944/com.allens.test E/XRetrofit: retrofitBack -> Date: Thu, 28 Dec 2017 09:29:10 GMT
12-28 04:29:07.337 3922-3944/com.allens.test E/XRetrofit: retrofitBack -> Server: Apache/2.4.17 (Win64) OpenSSL/1.0.2d PHP/5.6.16
12-28 04:29:07.337 3922-3944/com.allens.test E/XRetrofit: retrofitBack -> X-Powered-By: PHP/5.6.16
12-28 04:29:07.337 3922-3944/com.allens.test E/XRetrofit: retrofitBack -> Content-Length: 104
12-28 04:29:07.337 3922-3944/com.allens.test E/XRetrofit: retrofitBack -> Keep-Alive: timeout=5, max=100
12-28 04:29:07.337 3922-3944/com.allens.test E/XRetrofit: retrofitBack -> Connection: Keep-Alive
12-28 04:29:07.337 3922-3944/com.allens.test E/XRetrofit: retrofitBack -> Content-Type: application/json; charset=utf-8
12-28 04:29:07.338 3922-3944/com.allens.test E/XRetrofit: retrofitBack -> 
12-28 04:29:07.338 3922-3944/com.allens.test E/XRetrofit: retrofitBack -> {"is_success":true,"result":{"code":"9405f14110770bf8bd09d1397173e382eab923b19820b9330ce7d533cb3d4722"}}
12-28 04:29:07.338 3922-3944/com.allens.test E/XRetrofit: retrofitBack -> <-- END HTTP (104-byte body)

六: 最后在優(yōu)化

哈哈陈哑,自己封裝了一下,有興趣的小伙伴可以點(diǎn)擊查看伸眶,及使用

XRetrofit ,點(diǎn)擊查看如何使用

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末惊窖,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子厘贼,更是在濱河造成了極大的恐慌界酒,老刑警劉巖,帶你破解...
    沈念sama閱讀 221,635評(píng)論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件嘴秸,死亡現(xiàn)場(chǎng)離奇詭異盾计,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)赁遗,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,543評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門署辉,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人岩四,你說我怎么就攤上這事哭尝。” “怎么了剖煌?”我有些...
    開封第一講書人閱讀 168,083評(píng)論 0 360
  • 文/不壞的土叔 我叫張陵材鹦,是天一觀的道長逝淹。 經(jīng)常有香客問我,道長桶唐,這世上最難降的妖魔是什么栅葡? 我笑而不...
    開封第一講書人閱讀 59,640評(píng)論 1 296
  • 正文 為了忘掉前任,我火速辦了婚禮尤泽,結(jié)果婚禮上欣簇,老公的妹妹穿的比我還像新娘。我一直安慰自己坯约,他們只是感情好熊咽,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,640評(píng)論 6 397
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著闹丐,像睡著了一般横殴。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上卿拴,一...
    開封第一講書人閱讀 52,262評(píng)論 1 308
  • 那天衫仑,我揣著相機(jī)與錄音,去河邊找鬼堕花。 笑死惑畴,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的航徙。 我是一名探鬼主播如贷,決...
    沈念sama閱讀 40,833評(píng)論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼到踏!你這毒婦竟也來了杠袱?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,736評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤窝稿,失蹤者是張志新(化名)和其女友劉穎楣富,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體伴榔,經(jīng)...
    沈念sama閱讀 46,280評(píng)論 1 319
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡纹蝴,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,369評(píng)論 3 340
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了踪少。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片塘安。...
    茶點(diǎn)故事閱讀 40,503評(píng)論 1 352
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖援奢,靈堂內(nèi)的尸體忽然破棺而出兼犯,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 36,185評(píng)論 5 350
  • 正文 年R本政府宣布切黔,位于F島的核電站砸脊,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏纬霞。R本人自食惡果不足惜凌埂,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,870評(píng)論 3 333
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望诗芜。 院中可真熱鬧瞳抓,春花似錦、人聲如沸绢陌。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,340評(píng)論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽脐湾。三九已至,卻和暖如春叙淌,著一層夾襖步出監(jiān)牢的瞬間秤掌,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,460評(píng)論 1 272
  • 我被黑心中介騙來泰國打工鹰霍, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留闻鉴,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,909評(píng)論 3 376
  • 正文 我出身青樓茂洒,卻偏偏與公主長得像孟岛,于是被迫代替她去往敵國和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子督勺,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,512評(píng)論 2 359

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