Rxjava+Retrofit+okhttp3

rxjava+retrofit+okhttp3

一:項目簡介

重所周知 當下最流行的網絡請求的框架非rxjava+retrofit+okhttp3三合一了 但是在網絡上總是找不到一個比較全面的介紹 于是呼我自己研究了一套網絡請求的發開框架 目前已經寫入我開發的項目當中 目前還在學習的小伙伴們可以學習一下

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

Rxjava

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

舉例:觀察者(大s) 被觀察者(小s) 只有當小s發生了事件 或者說小s處罰了某個事件 大s 才會對小s 進行相應的處理 否則 大s 會一直處于一個等待的狀態

當然我說的可能會比較粗糙,我給大家介紹一個對Rxjava理解比較好的作者 相信你們看了他的講解 會比我這里更加的明白和理解。點擊-拋物線

Retrofit

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

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

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中使用的實體類接數據的,我是結合了rxjava的Subscriber(觀察者)來封裝的后面的文段我會在次講解 這里給大家留個懸念

注 :次處以在ApiManagerService類中聲明

顯而易見@POST,@GET的是請求方式,參數注解有@PATH和@Query,@QueryMap等。 @Query @QueryMap 參數依舊遵循了http協議 以鍵值對的形式進行請求。

到此接口我們就定義完成了需要來定義Retrofit對象來進行請求了

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

// OkHttp3 的監聽

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());//輸出請求前整個url

long t1 = System.nanoTime();

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

long t2 = System.nanoTime();

//? ? ? ? ? Log.v(TAG,response.request().url()+response.headers());//輸出一個請求的網絡信息

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自帶的監聽可以輸出整個url 還可以打印請求數據的時間 讓開發者很清楚的了解請求的耗時操作流程-真心的良心制作

//初始化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的監聽事件

2:清理數據的緩存

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

4:鏈接,讀,寫的時間 可以自己設置 當然不寫也無所謂啦

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作為回調適配器

.build();

初始化Retrofit

1:添加請求頭

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

3: 重點來 重點來 重點來重要的事情要說三遍

解析

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

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

大集合

@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() {

}

});

}

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

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

例如:

/**

* 設置公共參數

*/

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的解析設置

a)objectMapper.enable 一個簡單的映射過程 確保數據能夠全部請求過來

b)objectMapper.configure 設置當返回的參數為null時可自動執行序列化操作 當然 記得把你的實體類寫個空的構造方法。

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

2:ApiManager.apiManager.getReslut(result)

在此調用網絡請求

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

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

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

.subscribeOn(Schedulers.io())

.observeOn(AndroidSchedulers.mainThread())

設置流文件處理,設置執行在主線程。

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

你猜對了 我又給封裝了

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("無法連接服務器,請檢查網絡是否正常");

} 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("返回數據為空");

return;

} else {

try {

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

onMyNext(jsonStr);

} catch (JsonProcessingException e) {

e.printStackTrace();

}

}

}

} else {

//如果沒返回數據沒指向Result,打印數據。后期有返回特殊數據格式的時候可以單獨解析jsonStr

try {

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

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

LogUtil.printE(TAG, "原始數據" + 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:創建一個抽象類MySubscriber 繼承Subscriber 人有會問 為啥里面帶范型 T 呢

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

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

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

好了 當我的MySubscriber< T > 繼承Subscriber 我同樣也是實現了它內部的方法

onStart()

onCompleted()

onError(Throwable errorMsg)

onNext(T t)

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

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

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

項目地址 SmithGao https://github.com/SmithGao/rxjava_retrofit3.0_okhttp

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

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 229,362評論 6 537
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 99,013評論 3 423
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 177,346評論 0 382
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,421評論 1 316
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 72,146評論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,534評論 1 325
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,585評論 3 444
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,767評論 0 289
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 49,318評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 41,074評論 3 356
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,258評論 1 371
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,828評論 5 362
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,486評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,916評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,156評論 1 290
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,993評論 3 395
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,234評論 2 375

推薦閱讀更多精彩內容

  • Spring Cloud為開發人員提供了快速構建分布式系統中一些常見模式的工具(例如配置管理,服務發現,斷路器,智...
    卡卡羅2017閱讀 134,807評論 18 139
  • 轉載自:https://xiaobailong24.me/2017/03/18/Android-RxJava2.x...
    Young1657閱讀 2,033評論 1 9
  • 前段時間看了RxJava,發現跟他一起用的Retrofit,今天就把認識的他們倆個來總結梳理一下 一、什么是RxJ...
    毹毹閱讀 682評論 0 5
  • 前言RxJava和Retrofit也火了一段時間了,不過最近一直在學習ReactNative和Node相關的姿勢,...
    AFinalStone閱讀 558評論 0 0
  • 框架學習 1.RxJava RxJava的GitHub托管地址RxAndroid的GitHub托管地址 給 And...
    ElvenShi閱讀 1,051評論 0 0