Rxjava+Retrofit+okhttp3

rxjava+retrofit+okhttp3

一:項(xiàng)目簡介

重所周知 當(dāng)下最流行的網(wǎng)絡(luò)請(qǐng)求的框架非rxjava+retrofit+okhttp3三合一了 但是在網(wǎng)絡(luò)上總是找不到一個(gè)比較全面的介紹 于是呼我自己研究了一套網(wǎng)絡(luò)請(qǐng)求的發(fā)開框架 目前已經(jīng)寫入我開發(fā)的項(xiàng)目當(dāng)中 目前還在學(xué)習(xí)的小伙伴們可以學(xué)習(xí)一下

(此篇文章主要針對(duì)我的demo 很多細(xì)節(jié)的東西講的不是很到位 但是我會(huì)把我在網(wǎng)上看的比較好的文章貼上去 讓大家詳細(xì)的了解)

Rxjava

簡潔:對(duì)于rxjava的理解 我個(gè)人認(rèn)為就是一個(gè)異步線程一個(gè)基于事件處理的庫 讓人們可以更簡潔的處理一個(gè)事件的邏輯關(guān)系 簡單性 可讀性 重復(fù)性。再往深處的理解大家也可以認(rèn)為他是擴(kuò)展了開發(fā)者模式演變過來的

舉例:觀察者(大s) 被觀察者(小s) 只有當(dāng)小s發(fā)生了事件 或者說小s處罰了某個(gè)事件 大s 才會(huì)對(duì)小s 進(jìn)行相應(yīng)的處理 否則 大s 會(huì)一直處于一個(gè)等待的狀態(tài)

當(dāng)然我說的可能會(huì)比較粗糙,我給大家介紹一個(gè)對(duì)Rxjava理解比較好的作者 相信你們看了他的講解 會(huì)比我這里更加的明白和理解。點(diǎn)擊-拋物線

Retrofit

簡潔:Retrofit與okhttp共同出自于Square公司,retrofit就是對(duì)okhttp做了一層封裝。把網(wǎng)絡(luò)請(qǐng)求都交給給了Okhttp,我們只需要通過簡單的配置就能使用retrofit來進(jìn)行網(wǎng)絡(luò)請(qǐng)求。

Retrofit與Okhttp不同的是,Retrofit需要定義一個(gè)接口,用來返回我們的Call對(duì)象

public interface RequestServes {

@POST("mobileLogin/submit.html")

Call getReslut(@Query("loginname") String loginname);

}

public interface ApiManagerService {

@POST("/biz/bizserver/news/list.do")

Observable getReslut(@QueryMap Map option);

}

我先說一下Result類,這是我自己demo中使用的實(shí)體類接數(shù)據(jù)的,我是結(jié)合了rxjava的Subscriber(觀察者)來封裝的后面的文段我會(huì)在次講解 這里給大家留個(gè)懸念

注 :次處以在ApiManagerService類中聲明

顯而易見@POST,@GET的是請(qǐng)求方式,參數(shù)注解有@PATH和@Query,@QueryMap等。 @Query @QueryMap 參數(shù)依舊遵循了http協(xié)議 以鍵值對(duì)的形式進(jìn)行請(qǐng)求。

到此接口我們就定義完成了需要來定義Retrofit對(duì)象來進(jìn)行請(qǐng)求了

俺就不再廢話了 直接貼上代碼 讓大家伙看個(gè)明白地

// OkHttp3 的監(jiān)聽

private static class LogInterceptor implements Interceptor {

@Override

public okhttp3.Response intercept(Chain chain) throws IOException {

Request request = chain.request();

Log.e(TAG, "okhttp3:" + request.toString());//輸出請(qǐng)求前整個(gè)url

long t1 = System.nanoTime();

okhttp3.Response response = chain.proceed(chain.request());

long t2 = System.nanoTime();

//? ? ? ? ? Log.v(TAG,response.request().url()+response.headers());//輸出一個(gè)請(qǐng)求的網(wǎng)絡(luò)信息

okhttp3.MediaType mediaType = response.body().contentType();

String content = response.body().string();

Log.e(TAG, "response body:" + content);//輸出返回信息

return response.newBuilder()

.body(okhttp3.ResponseBody.create(mediaType, content))

.build();

}

}

這是OkHttp3自帶的監(jiān)聽可以輸出整個(gè)url 還可以打印請(qǐng)求數(shù)據(jù)的時(shí)間 讓開發(fā)者很清楚的了解請(qǐng)求的耗時(shí)操作流程-真心的良心制作

//初始化OkHttp3的初始化

private static OkHttpClient client = new OkHttpClient.Builder()

.addInterceptor(new LogInterceptor())

.cache(new Cache(new File("C://okhttp"), 10 * 1024 * 102))//緩存

.retryOnConnectionFailure(true)

//? ? ? ? ? .connectTimeout(3, TimeUnit.SECONDS)

//? ? ? ? ? .writeTimeout(5, TimeUnit.SECONDS)

//? ? ? ? ? .readTimeout(5, TimeUnit.SECONDS)

.build();

這是化OkHttp3的初始化

1:添加OKhttp3的監(jiān)聽事件

2:清理數(shù)據(jù)的緩存

3:在鏈接失敗后重新鏈接

4:鏈接,讀,寫的時(shí)間 可以自己設(shè)置 當(dāng)然不寫也無所謂啦

5:最后 build()

//初始化Retrofit

private static final Retrofit sRetrofit = new Retrofit.Builder()

.baseUrl("http://api.1-blog.com")

.client(client)

.addConverterFactory(JacksonConverterFactory.create())//加入jackjson解析

.addCallAdapterFactory(RxJavaCallAdapterFactory.create()) // 使用RxJava作為回調(diào)適配器

.build();

初始化Retrofit

1:添加請(qǐng)求頭

2:添加okhttp的對(duì)象(前面也說了-retrofit就是對(duì)okhttp做了一層封裝)

3: 重點(diǎn)來 重點(diǎn)來 重點(diǎn)來重要的事情要說三遍

解析

Gson: com.squareup.retrofit2:converter-gson

Jackson: com.squareup.retrofit2:converter-jackson

Moshi: com.squareup.retrofit2:converter-moshi

Protobuf: com.squareup.retrofit2:converter-protobuf

Wire: com.squareup.retrofit2:converter-wire

Simple XML: com.squareup.retrofit2:converter-simplexml

Scalars (primitives, boxed, and String): com.squareup.retrofit2:converter-scalars

總有一款你需要的解析形式 附贈(zèng)官網(wǎng)retrofit 官網(wǎng)地址:http://square.github.io/retrofit/啟動(dòng)你的翻譯器慢慢看吧!(英語大神除外哈) 大家可以看到 我添加的是jackjson解析 這是我demo中所需要的 后續(xù)一起講解。 在此介紹一片文章點(diǎn)擊一下吧

大集合

@OnClick(R.id.btn)

void more() {

Map result = ApiManager.getBasicMap();

result.put("size", "3");

ApiManager.apiManager.getReslut(result)

.subscribeOn(Schedulers.io())

.observeOn(AndroidSchedulers.mainThread())

.subscribe(new MySubscriber() {

@Override

public void onMyNext(String jsonStr) {

LogUtil.defLog(jsonStr);

data.setText(jsonStr);

}

@Override

public void onMyError(String msg) {

}

@Override

public void onMyCompleted() {

}

});

}

朋友 看到這請(qǐng)你告訴我 你是不是一臉的懵b 別著急 前面介紹了半天 現(xiàn)在正主正在一點(diǎn)點(diǎn)的出來了 咱們一步步的走我來給你解釋一下

###### 1 :Map集合ApiManager.getBasicMap() 自己封裝了一下 可以將以后項(xiàng)目中的公共參數(shù)放進(jìn)去

例如:

/**

* 設(shè)置公共參數(shù)

*/

public static Map getBasicMap() {

if (objectMapper == null) {

objectMapper = new ObjectMapper();

objectMapper.enable(DeserializationFeature.ACCEPT_SINGLE_VALUE_AS_ARRAY);

objectMapper.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false);

}

if (map == null) {

map = new HashMap<>();

} else {

map.clear();

}

//打印MAP

Set> entrySet = map.entrySet();

for (Map.Entry entry : entrySet) {

LogUtil.printI(LogUtil.APP_TAG, entry.getKey() + "http://" + entry.getValue() + "");

}

return map;

}

其中objectMapper 即是jackjson的解析設(shè)置

a)objectMapper.enable 一個(gè)簡單的映射過程 確保數(shù)據(jù)能夠全部請(qǐng)求過來

b)objectMapper.configure 設(shè)置當(dāng)返回的參數(shù)為null時(shí)可自動(dòng)執(zhí)行序列化操作 當(dāng)然 記得把你的實(shí)體類寫個(gè)空的構(gòu)造方法。

以上兩個(gè)配置我個(gè)人介意還是加上 省的大家走很多的彎路 (我不哭)

2:ApiManager.apiManager.getReslut(result)

在此調(diào)用網(wǎng)絡(luò)請(qǐng)求

public static ApiManagerService apiManager = sRetrofit.create(ApiManagerService.class);

在開始介紹的由Retrofit定義的接口類 各種的封裝啊。。。。 OK

3:接下來正主來了 rxjava重出江湖

.subscribeOn(Schedulers.io())

.observeOn(AndroidSchedulers.mainThread())

設(shè)置流文件處理,設(shè)置執(zhí)行在主線程。

4:.subscribe(new MySubscriber() What is fuck?

你猜對(duì)了 我又給封裝了

public abstract class MySubscriber extends Subscriber {

String TAG = MySubscriber.class.getName();

@Override

public void onStart() {

onMyStart();

}

@Override

public void onCompleted() {

onMyCompleted();

}

@Override

public void onError(Throwable errorMsg) {

String stringErr = errorMsg.getLocalizedMessage();

//TODO 需要完善異常的判斷

if (stringErr.contains("UnknownHostException")) {

onMyError("無法連接服務(wù)器,請(qǐng)檢查網(wǎng)絡(luò)是否正常");

} else {

onMyError(stringErr);

}

}

@Override

public void onNext(T t) {

if (Result.class.isInstance(t)) {

Result result = (Result) t;

if (!result.getStatus().equals("success")) {

onMyError(result.getInfo());

} else {

if (null == result.getData() && "".equals(result.getData())) {

onMyError("返回?cái)?shù)據(jù)為空");

return;

} else {

try {

String jsonStr = ApiManager.objectMapper.writeValueAsString(result.getData());

onMyNext(jsonStr);

} catch (JsonProcessingException e) {

e.printStackTrace();

}

}

}

} else {

//如果沒返回?cái)?shù)據(jù)沒指向Result,打印數(shù)據(jù)。后期有返回特殊數(shù)據(jù)格式的時(shí)候可以單獨(dú)解析jsonStr

try {

String jsonStr = ApiManager.objectMapper.writeValueAsString(t);

//? ? ? ? ? ? ? ? onMyNext(jsonStr);

LogUtil.printE(TAG, "原始數(shù)據(jù)" + jsonStr);

} catch (JsonProcessingException e) {

}

}

}

public abstract void onMyStart();

public abstract void onMyNext(String jsonStr);

public abstract void onMyError(String msg);

public abstract void onMyCompleted();

雖然這里類在代碼里有 但是我還是選擇了全部貼出來 講解開始:

1:創(chuàng)建一個(gè)抽象類MySubscriber 繼承Subscriber 人有會(huì)問 為啥里面帶范型 T 呢

范型的定義:泛型,即“參數(shù)化類型”。一提到參數(shù),最熟悉的就是定義方法時(shí)有形參,然后調(diào)用此方法時(shí)傳遞實(shí)參。那么參數(shù)化類型怎么理解呢?顧名思義,就是將類型由原來的具體的類型參數(shù)化,類似于方法中的變量參數(shù),此時(shí)類型也定義成參數(shù)形式(可以稱之為類型形參),然后在使用/調(diào)用時(shí)傳入具體的類型(類型實(shí)參)

所以在接收參數(shù)的時(shí)候 我可以任意的將參數(shù)實(shí)例化(避免了參數(shù)寫死) 說大白話就是:我在項(xiàng)目a中的根節(jié)點(diǎn)是{1,2,3}那我在項(xiàng)目b中的根節(jié)點(diǎn)可能就要變成{a,b,c,d}

值得注意的是在你的實(shí)體類Result中 也要使用范型來接收數(shù)據(jù)即Result < T > 否則無效,甚至報(bào)錯(cuò)。到時(shí)候大家可以往底層的代碼看看 其實(shí)Subscriber是實(shí)現(xiàn)了觀察者Observer的方法的 在這里我不再深多解釋-雙手將鏈接奉上點(diǎn)擊-拋物線

好了 當(dāng)我的MySubscriber< T > 繼承Subscriber 我同樣也是實(shí)現(xiàn)了它內(nèi)部的方法

onStart()

onCompleted()

onError(Throwable errorMsg)

onNext(T t)

同時(shí) 我自己也寫了四個(gè)抽象的方法來作為整個(gè)抽象類的返回值 在此處 onNext(T t) 承載了返回的數(shù)據(jù) 到時(shí)大家可以根據(jù)自己(公司的)項(xiàng)目來更改 ,方法中 唯一必須要寫的就是

String jsonStr = ApiManager.objectMapper.writeValueAsString(result.getData());

此方法是jackjson中 將返回的json 轉(zhuǎn)化成字符串的形式返回出去,在我的MainActivity中 我又自己寫了個(gè)ParseJsonUtil類 來處理返回的字符串(這樣很大問題解決了重復(fù)性) 可轉(zhuǎn)化集合 或者單個(gè)的實(shí)體 具體的可在log中打印出來 哦 對(duì)了 我的GoodVideoBean只是個(gè)樣品 沒有實(shí)例的數(shù)據(jù)返回 大家可以嘗試寫一下 假如在又不明白的可以加我的qq 2215719882 來詢問我

項(xiàng)目地址 SmithGao https://github.com/SmithGao/rxjava_retrofit3.0_okhttp

最后 歡迎 start --屌絲程序員一枚

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn),斷路器,智...
    卡卡羅2017閱讀 136,533評(píng)論 19 139
  • 轉(zhuǎn)載自:https://xiaobailong24.me/2017/03/18/Android-RxJava2.x...
    Young1657閱讀 2,106評(píng)論 1 9
  • 前段時(shí)間看了RxJava,發(fā)現(xiàn)跟他一起用的Retrofit,今天就把認(rèn)識(shí)的他們倆個(gè)來總結(jié)梳理一下 一、什么是RxJ...
    毹毹閱讀 729評(píng)論 0 5
  • 前言RxJava和Retrofit也火了一段時(shí)間了,不過最近一直在學(xué)習(xí)ReactNative和Node相關(guān)的姿勢,...
    AFinalStone閱讀 625評(píng)論 0 0
  • 框架學(xué)習(xí) 1.RxJava RxJava的GitHub托管地址RxAndroid的GitHub托管地址 給 And...
    ElvenShi閱讀 1,141評(píng)論 0 0

友情鏈接更多精彩內(nèi)容