1. 程式人生 > >retrofit+rxjava有這個demo,想不懂都難

retrofit+rxjava有這個demo,想不懂都難

前言

RxJava和Retrofit也火了一段時間了,不過最近一直在學習ReactNative和Node相關的姿勢,一直沒有時間研究這些新東西,最近有個專案準備寫,打算先用Android寫一個Demo出來,卻發現Android的世界發生了天翻地覆的變化,EventBus和OKHttp啥的都不見了,RxJava和Retrofit是什麼鬼?

好吧,到Github上耐著性子看過了RxJava和Retrofit的介紹和幾個Demo,原來Android的大神Jake Wharton為Retrofit這個專案貢獻了這麼多的程式碼,沒有道理不用了。

如果你對Retrofit不熟悉就先看

Retrofit官網

當然也有很多RxJava與Retrofit的文章,但是我覺得很多大家都很糾結的功能都沒有被總結出來,所以才有了此篇文章。

歡迎大家拍磚。

接下來進入正文,我是從下面幾個角度去思考RxJava與Retrofit結合的。

  1. RxJava如何與Retrofit結合
  2. 相同格式的Http請求資料該如何封裝
  3. 相同格式的Http請求資料統一進行預處理
  4. 如何取消一個Http請求 -- 觀察者之間的對決,Oberver VS Subscriber
  5. 一個需要ProgressDialog的Subscriber該有的樣子

1.RxJava如何與Retrofit結合

1.1 基本頁面

先扔出build.gradle檔案的內容

dependencies {
    compile fileTree(dir:'libs', include:['*.jar'])
    testCompile 'junit:junit:4.12'
    compile 'com.android.support:appcompat-v7:23.2.0'
    compile 'io.reactivex:rxjava:1.1.0'
    compile 'io.reactivex:rxandroid:1.1.0'
    compile 'com.squareup.retrofit2:retrofit:2.0.0-beta4'
compile 'com.squareup.retrofit2:converter-gson:2.0.0-beta4' compile 'com.squareup.retrofit2:adapter-rxjava:2.0.0-beta4' compile 'com.google.code.gson:gson:2.6.2' compile 'com.jakewharton:butterknife:7.0.1'}

也就是說本文是基於RxJava1.1.0和Retrofit 2.0.0-beta4來進行的。 新增rxandroid是因為rxjava中的執行緒問題。

下面先搭建一個基本的頁面,頁面很簡單,先來看檔案目錄結構目錄結構

activity_main.xml的程式碼如下:

<?xml version="1.0" encoding="utf-8"?><RelativeLayoutxmlns:android="http://schemas.android.com/apk/res/android"xmlns:tools="http://schemas.android.com/tools"android:layout_width="match_parent"android:layout_height="match_parent"android:paddingBottom="@dimen/activity_vertical_margin"android:paddingLeft="@dimen/activity_horizontal_margin"android:paddingRight="@dimen/activity_horizontal_margin"android:paddingTop="@dimen/activity_vertical_margin"tools:context=".activity.MainActivity"><Buttonandroid:id="@+id/click_me_BN"android:layout_width="match_parent"android:layout_height="wrap_content"android:layout_alignParentBottom="true"android:padding="5dp"android:text="點我"android:textSize="16sp"/><TextViewandroid:id="@+id/result_TV"android:layout_width="match_parent"android:layout_height="match_parent"android:layout_above="@id/click_me_BN"android:text="Hello World!"android:textSize="16sp"/></RelativeLayout>

MainActivity.java的程式碼如下:

package com.queen.rxjavaretrofitdemo.activity;import android.os.Bundle;import android.support.v7.app.AppCompatActivity;import android.widget.Button;import android.widget.TextView;import com.queen.rxjavaretrofitdemo.R;import butterknife.Bind;import butterknife.ButterKnife;import butterknife.OnClick;publicclassMainActivity extends AppCompatActivity{@Bind(R.id.click_me_BN)Button clickMeBN;@Bind(R.id.result_TV)TextView resultTV;@Overrideprotectedvoid onCreate(Bundle savedInstanceState){super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);ButterKnife.bind(this);}@OnClick(R.id.click_me_BN)publicvoid onClick(){
        getMovie();}//進行網路請求privatevoid getMovie(){}}

注意不要忘記加網路許可權

<uses-permissionandroid:name="android.permission.INTERNET"/>

1.2 只用Retrofit

我們準備在getMovie方法中進行網路請求,我們先來看看只使用Retrofit是如何進行的。

我們使用豆瓣電影的Top250做測試連線,目標地址為

https://api.douban.com/v2/movie/top250?start=0&count=10

至於返回的資料格式,大家自己訪問下連結就看到了,太長就不放進來了。

首先我們要根據返回的結果封裝一個Entity,暫命名為MovieEntity,程式碼就不貼了。

接下來我們要建立一個介面取名為MovieService,程式碼如下:

publicinterfaceMovieService{@GET("top250")Call<MovieEntity> getTopMovie(@Query("start")int start,@Query("count")int count);}

回到MainActivity之中,我們來寫getMovie方法的程式碼

//進行網路請求privatevoid getMovie(){String baseUrl ="https://api.douban.com/v2/movie/";Retrofit retrofit =newRetrofit.Builder().baseUrl(baseUrl).addConverterFactory(GsonConverterFactory.create()).build();MovieService movieService = retrofit.create(MovieService.class);Call<MovieEntity> call = movieService.getTopMovie(0,10);
    call.enqueue(newCallback<MovieEntity>(){@Overridepublicvoid onResponse(Call<MovieEntity> call,Response<MovieEntity> response){
            resultTV.setText(response.body().toString());}@Overridepublicvoid onFailure(Call<MovieEntity> call,Throwable t){
            resultTV.setText(t.getMessage());}});}

以上為沒有經過封裝的、原生態的Retrofit寫網路請求的程式碼。 我們可以封裝建立Retrofit和service部分的程式碼,然後Activity用建立一個Callback作為引數給Call,這樣Activity中只關注請求的結果,而且Call有cancel方法可以取消一個請求,好像沒Rxjava什麼事了,我覺得可以寫到這就下班了~

接下來我們要面對的問題是這樣的 如果我的Http返回資料是一個統一的格式,例如

{"resultCode":0,"resultMessage":"成功","data":{}}

我們如何對返回結果進行一個統一的處理呢?

另外,我的ProgressDialog的show方法應該在哪呼叫呢?看樣子只能在getMovie()這個方法裡面呼叫了,換個地方發出請求就要在對應的Listener裡面寫一遍show()的程式碼,其實挺鬧心。

而且錯誤請求我也想集中處理掉不要貼重複的程式碼。

我們先來看結合了Rxjava之後,事情有沒有變化的可能。當然即便是不用Rxjava,依舊能夠做很多的封裝,只是比較麻煩。

如需檢視專案程式碼 --> 程式碼地址:

https://github.com/tough1985/RxjavaRetrofitDemo

選擇Tag -> step1

1.3 新增Rxjava

Retrofit本身對Rxjava提供了支援。

新增Retrofit對Rxjava的支援需要在Gradle檔案中新增

compile 'com.squareup.retrofit2:adapter-rxjava:2.0.0-beta4'

當然我們已經新增過了。

然後在建立Retrofit的過程中新增如下程式碼:

Retrofit retrofit =newRetrofit.Builder().baseUrl(baseUrl).addConverterFactory(GsonConverterFactory.create()).addCallAdapterFactory(RxJavaCallAdapterFactory.create()).build();

這樣一來我們定義的service返回值就不在是一個Call了,而是一個Observable

重新定義MovieService

publicinterfaceMovieService{@GET("top250")Observable<MovieEntity> getTopMovie(@Query("start")int start,@Query("count")int count);}

getMovie方法改為:

//進行網路請求privatevoid getMovie(){String baseUrl ="https://api.douban.com/v2/movie/";Retrofit retrofit =newRetrofit.Builder().baseUrl(baseUrl).addConverterFactory(GsonConverterFactory.create()).addCallAdapterFactory(RxJavaCallAdapterFactory.create()).build();MovieService movieService = retrofit.create(MovieService.class);

    movieService.getTopMovie(0,10).subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(newSubscriber<MovieEntity>(){@Overridepublicvoid onCompleted(){Toast.makeText(MainActivity.this,"Get Top Movie Completed",Toast.LENGTH_SHORT).show();}@Overridepublicvoid onError(Throwable e){
                    resultTV.setText(e.getMessage());}@Overridepublicvoid onNext(MovieEntity movieEntity){
                    resultTV.setText(movieEntity.toString());}});}

這樣基本上就完成了Retrofit和Rxjava的結合,但是我知道你們當然不會滿意的。

接下來我們把建立Retrofit的過程封裝一下,然後希望Activity建立Subscriber物件傳進來。

如需檢視專案程式碼 --> 程式碼地址:

選擇Tag -> step2

1.4 將請求過程進行封裝

建立一個物件HttpMethods

publicclassHttpMethods{publicstatic final String BASE_URL ="https://api.douban.com/v2/movie/";privatestatic final int DEFAULT_TIMEOUT =5;privateRetrofit retrofit;privateMovieService movieService;//構造方法私有privateHttpMethods(){//手動建立一個OkHttpClient並設定超時時間OkHttpClient.Builder httpClientBuilder =newOkHttpClient.Builder();
        httpClientBuilder.connectTimeout(DEFAULT_TIMEOUT,TimeUnit.SECONDS);

        retrofit =newRetrofit.Builder().client(httpClientBuilder.build()).addConverterFactory(GsonConverterFactory.create()).addCallAdapterFactory(RxJavaCallAdapterFactory.create()).baseUrl(BASE_URL).build();

        movieService = retrofit.create(MovieService.class);}//在訪問HttpMethods時建立單例privatestaticclassSingletonHolder{privatestatic final HttpMethods INSTANCE =newHttpMethods();}//獲取單例publicstaticHttpMethods getInstance(){returnSingletonHolder.INSTANCE;}/**
     * 用於獲取豆瓣電影Top250的資料
     * @param subscriber 由呼叫者傳過來的觀察者物件
     * @param start 起始位置
     * @param count 獲取長度
     */publicvoid getTopMovie(Subscriber<MovieEntity> subscriber,int start,int count){
        movieService.getTopMovie(start, count).subscribeOn
            
           

相關推薦

retrofit+rxjava這個demo

前言 RxJava和Retrofit也火了一段時間了,不過最近一直在學習ReactNative和Node相關的姿勢,一直沒有時間研究這些新東西,最近有個專案準備寫,打算先用Android寫一個Demo出來,卻發現Android的世界發生了天翻地覆的變化,EventBus和OKHttp啥的都不見了

使用springmvc 接收上傳圖片在 手機 ios 上圖片上傳就報錯 沒有就報下面這個錯誤然後在pc端跟安卓手機上就這個錯誤這是為什麼呢?

七月 18, 2018 4:04:22 下午 org.apache.catalina.core.StandardWrapperValve invoke 嚴重: Servlet.service() for servlet [springMVC] in context with

了Git這個功能再也需要依賴IDE了!

大家好,今天給大家介紹一個隱藏的功能——搜尋。 我們在寫程式碼的時候經常遇到的一種情況就是,我們想要知道某一個函式是怎麼定義的,這樣我們才能知道該如何呼叫它。如果程式碼少的話我們當然可以自己人肉查詢,但是如果程式碼量很大的話,人肉查詢顯然就不行了。如果使用IDE的話,現在的IDE當中當然一般都繼承了這個功能,

節目--標籤 0 , 1矩陣的建立(0代表節目這個標籤1代表沒有這個標籤)

原始的節目及所包含的標籤型別對應的格式如下: import pandas as pd import numpy as np import os os.chdir('E:/廣電大資料營銷推薦專案案例/資料清洗/電視節目資訊資料預處理') tv = pd.read_csv('./wordsb

你們敲程式碼的真的這個嘛?

還記的這個梗嘛! 雖說不是故意來調侃技術人員的,但也充分說明,技術工種的不受重視等等! 有想過出來創業嘛!!! 只要你會錄影,會說話,就ok嘍!!! 近些年,一系列標誌性的事件讓內容付費漸漸成為時尚 。2016年5月15日,付費語音問答平臺--"分答"上線。通過這一平臺,你可以快速地找到能給自己提供幫

可憐的Sun公司因為收購了MySQL賣自己了了

分享一下我老師大神的人工智慧教程!零基礎,通俗易懂!http://blog.csdn.net/jiangjunshow 也歡迎大家轉載本篇文章。分享知識,造福人民,實現我們中華民族偉大復興!        

32歲的微胖女神堅持健身腹部卻贅肉失魅..

南樂縣 阿里巴巴集團董事局主席馬雲發表致股東的公開信表示:生意難做之時,正是阿里巴巴兌現“讓天下沒有難做的生意”的使命之時。,阿里巴巴(NYSE:BABA)今日釋出了截至2018年9月30日的2019財年第二季度財報(注:阿里巴巴財年與自然年不同步,從每年的4月1日開始,至第二年的3月31日結束)。 財報中

高承實:做鏈改專案清楚一定會成功

有道是:有道而乏術者不能發揮其所長,精於術而乏道者亦不能長久,精於術而明道者乃高人也!今日鏈視界要採訪的這位高人,是高承實博士。 高博士認為區塊鏈專案的發展需要以道統術,以術得道。他在道的層面將人類對經濟和社會的治理方式分為組織管理和自發執行,將具體的應用工具稱之為術,具體包括方法、手

中登公司統計資料好像問題

中國證券登記結算有限責任公司 在網上公佈每週統計資料 http://www.chinaclear.cn/zdjs/xmzkb/center_mzkb.shtml 俺一直跟蹤中登公司釋出的新開戶資料,比如這個 https://dszh.org/show.php?f=1&

iOS 朋友圈點贊評論釋出朋友圈要的

最近寫了一個朋友圈的點贊、評論蓋樓、釋出圖文朋友圈的demo 仿微信寫的,具體的實現,我釋出到git上了。釋出朋友圈,簡單寫了兩種方法,看你喜歡哪種了,有問題可以私信我 因為程式碼挺多的,說的再多,不如直接demo了,邏輯實現方法自己去看。最後一個釋出朋友的

誰養魚這是一個很有趣的邏輯推理題傳說是愛因斯坦提出來的他宣稱世界上只有2%的人能解出這個題目傳說一定屬實但是這個推理題還是很有意思的

題目:據說有五個不同顏色的房間排成一排,每個房間裡分別住著一個不同國籍的人,每個人都喝 一種特定品牌的飲料,抽一種特定品牌的煙,養一種寵物,沒有任意兩個人抽相同品牌的香菸,或喝相同品牌的飲料,或養相同的寵物,問題是誰在養魚作為寵物? 為了尋找答案,給出了十五條線索: 英國人

一天在了因為你的身邊不再需要我

   幾年之前,村裡偶遇當時可能被你迷人的外表所迷惑,加了聯絡方式,之後石沉大海不再聯絡    最近一兩年遊戲讓我們 在一次的溝通但是感覺這東西真讓人琢磨不定。    去年的集五福讓我們再一次的聯絡,但是卻降低了我在你心中的形象。    往後我的一句我想你,劈頭蓋臉的神經病澆

W10系統下用Anaconda裝tensorflow你想不到多簡單用時到10min

     我曾在Ubuntu系統下裝過很多次tensorflow,成功過也失敗過,總是遇到不同的問題,只好碰運氣了。以前在w10系統也裝過tf(tensorflow),但是也總是出現錯誤,昨天重新安裝了w10系統,想再嘗試一下用w10安裝tf,結果不到十分鐘就安裝成功了,特此

型別化(Type)的DataSet (使用強型別的DataSet。定義的資料庫表一定要主鍵否則能使用)

使用強型別的DataSet的時候一定要設定主鍵,假如說你在拖一個表到資料集來建立強型別DataSet的時候 而那個表又沒有設定主鍵 那麼你只有在資料集裡把你拖入的那個表刪除,重新拖入。或者點選你拖入到資料集的那個表,把滑鼠移動到 "表名+TableAdapter"欄 其實也

文件驅動 —— 表單元件(五):基於Ant Design Vue 的表單控制元件的demo再也需要寫程式碼了。

# 原始碼 [https://github.com/naturefwvue/nf-vue3-ant](https://github.com/naturefwvue/nf-vue3-ant) # 特點 * 只需要更改meta,既可以切換表單 * 可以統一修改樣式,統一升級,以最小的代價,應對UI的升級、切換

numpy但很利害

num ber number clas com es2017 highlight ima sort 慢慢有感覺。。 截幾個圖看看。 import numpy as np np.random.seed(42) complex_numbers = np.random

20)內聯函數(其實

簡單 定義 技術分享 缺失 如果 line src 語法 調用 1)C語言中有宏函數的概念,宏函數的特點是內嵌到調用代碼中去,避免了函數調用的開銷。但是由於宏函數的處理發生在預處理階段,缺失了語法檢測和有可能帶來的語意差錯。 2)看著很高端,其實很無腦 3)如果你的函數,

05_Linux常用檔案系統命令詳解我吃s!

常用檔案系統命令詳解 磁碟管理: cd change directory 常使用方式: cd sourcedir   進入使用者主目錄 cd ~   進入使用者主目錄 cd -  

十個python入門基礎小案例的童鞋要注意

今天給大家分享十個Python入門級別的小案例。這十個案例的難度不高,但是對於知識的使用非常全面,很適合小白在學習的初期建立學習信心和增加熟練度。每個案例下都有或多或少的思路分析,希望對大家有幫助 推薦下小編的Python學習群:629440234,不管你是小白還是大牛,小編我都歡

你學C語言是因為編寫C程式的7個步驟

雲上傘 編寫一個C程式,這是一個很複雜的問題,面對複雜的問題,學會把它分解成若干個小問題,一個個小問題的解決,最後思路很清晰地解決掉這個“麻煩”。 一般情況下,我們把編寫C程式分為7個步驟,懂得了後,編寫程式就會有整體的思路,再也不像從前那樣毫無頭緒了。 你學不懂C語言,是因為不懂編