最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Kotlin下Rxjava的基礎(chǔ)用法及流式調(diào)用示例詳解

 更新時間:2022年11月30日 14:28:12   作者:i聽風(fēng)逝夜  
這篇文章主要為大家介紹了Kotlin下Rxjava的基礎(chǔ)用法及流式調(diào)用示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪

前言

萬事開頭難,寫文章也是,現(xiàn)在越來越不知道開頭怎么寫了,所以在前言中,簡單介紹下RxJava吧,第一次聽說還是以前做Android開發(fā)的時候,那時候好多庫中都使用了Rxjava,而在網(wǎng)絡(luò)請求中,也有很多都是使用Rxjava去寫,但自己卻沒怎么在項目中寫過,而在搜索資料中發(fā)現(xiàn),微信中搜rxjava時,最多介紹他的還是Android開發(fā)者,所以今天來記錄下。

而所謂的響應(yīng)式編程,就是一種用于應(yīng)用程序異步編程的技術(shù),他是一個通用的思想,類似與AOP,不只是在java中才有。他專注于對數(shù)據(jù)的變化做出反應(yīng),例如,有一個數(shù)據(jù)源(這里被稱為生產(chǎn)者),一個數(shù)據(jù)目標(biāo)(這里被成為消費者),然后在將消費者連接到訂閱者之后,響應(yīng)式編程框架負責(zé)將生產(chǎn)者生產(chǎn)的數(shù)據(jù)推送給消費者,一個可觀察對象可以有任意數(shù)量的訂閱者。

而對于一些思想上的框架,類似于Spring,源碼上大體還是比較難的,畢竟就算是人,在思想上跨越也是有難度的,但對于RxJava來說,源碼也不是很多,所以在以后會嘗試介紹他的源碼實現(xiàn),而使用Rxjava的好處不是在于實現(xiàn)了什么具體的技術(shù)功能,比如使用CGLIB可以實現(xiàn)動態(tài)代理的技術(shù),使用JDBC可以進行數(shù)據(jù)查詢,而沒有rxjava,我們的代碼還可以借助Java8的Stream、CompletableFuture來實現(xiàn)。

而rxjava的好處在于讓代碼更簡潔、優(yōu)雅,通過他的鏈?zhǔn)秸{(diào)用,消除嵌套等。

在下面的例子中,我們會使用Kotlin來做示范。

基礎(chǔ)用法

在這里,Observable 字面意思是可觀察者,他表示數(shù)據(jù)源,通常,一旦訂閱者開始收聽,他們就會開始提供數(shù)據(jù),而just表示僅僅,僅僅生產(chǎn)的數(shù)據(jù)是一個"T",即泛型類型,在這里是String。

而subscribe表示訂閱,當(dāng)訂閱后,他會收到Observable生產(chǎn)的數(shù)據(jù),來消費。

fun main() {
     Observable.just("hello rxjava").subscribe {
         println(it)
     }
}
輸出:
hello rxjava

fromXXX

而上面說到,just表示僅僅,在rxjava中,不僅僅是具體的數(shù)據(jù),還可以是Callable、Array、Future對象等,詳細可以看fromXXX等方法,最終的結(jié)果由rxjava調(diào)用后如Callable的結(jié)果后,傳遞給訂閱者。

fun main() {
    Observable.fromCallable {
        println("callable")
        "hello rxjava"
    }.subscribe {
        println(it)
    }
}

create

這個方法給我了我們手動執(zhí)行的能力,即傳遞數(shù)據(jù)到訂閱者是我們手動執(zhí)行的。

fun main() {
    Observable.create<String> {
        it.onNext("hello")
        it.onError(IllegalArgumentException("錯誤"))
        it.onComplete()
    }.subscribe ({
        println(it)
    },{
        println(it.message)
    },{
        println("完成")
    })
}

interval & timer

還可以通過interval實現(xiàn)固定間隔定時。

fun main() {
    val observable = Observable.interval(1, TimeUnit.SECONDS)
    observable.subscribe {
        println(it)
    }
    observable.subscribe {
        println(it)
        Thread.sleep(2000)
    }
    Thread.sleep(100000);
}

而timer方法則是延遲N時間后,發(fā)送數(shù)據(jù)到訂閱者.

fun main() {
    val observable = Observable.timer(2, TimeUnit.SECONDS)
    observable.subscribe {
        println(it)
    }
    observable.subscribe {
        println(it)
        Thread.sleep(2000)
    }
    Thread.sleep(100000);
}

指定線程

而使用上面方法有一個好處,即生產(chǎn)者可以在子線程中完成,而實際消費的時候在主線程,這在Android可謂是一種福利,如下。

fun main() {
    val threadPool = Executors.newCachedThreadPool()
    val anyFuture = threadPool.submit(Callable {
        Thread.sleep(2000)
        "hello"
    })
    Observable.fromFuture(anyFuture).subscribe {
        println(it)
    }
}

而如果擔(dān)心等待時間問題,可是使用第二個重載方法,指定一個超時時間,而subscribe還有兩個主要參數(shù)我們沒說,一個是error發(fā)生錯誤時回調(diào),一個是complete完成時回調(diào),但在發(fā)生錯誤后,complete是不會回調(diào)的。

fun main() {
    val threadPool = Executors.newCachedThreadPool()
    val anyFuture = threadPool.submit(Callable {
        Thread.sleep(2000)
        "hello"
    })
    Observable.fromFuture(anyFuture,1,TimeUnit.SECONDS).subscribe({
        println(it)
    },{
        println("錯誤")
    },{
        println("完成")
    })
}

observeOn & subscribeOn

但你以為這就結(jié)束了嗎,不,rxjava提供了豐富的線程切換,observeOn & subscribeOn這兩個方法就是用來指定在哪里運行,Schedulers.newThread()表示在新線程,但rxjava實現(xiàn)的線程中,是守護線程,也就是當(dāng)主線程退出后,他們也會自動退出,而在下面的例子中,如果在最后不加sleep,會導(dǎo)致主線程退出后,rxjava的所有線程在可能沒執(zhí)行完成后也將退出。

fun main() {
    Observable.create<String> {
        println(Thread.currentThread().isDaemon)
        it.onNext("hello")
    }
        .observeOn(Schedulers.newThread())
        .subscribeOn(Schedulers.newThread())
        .subscribe {
            println(Thread.currentThread().name)
            println(it)
        }
    Thread.sleep(10000)
}

而如果想自定義線程,也是支持的。

fun createSchedulers(): Scheduler {
    return Schedulers.from {
        thread { it.run() }
    }
}
fun main() {
    Observable.create<String> {
        it.onNext("hello")
    }
        .observeOn(createSchedulers())
        .subscribeOn(Schedulers.newThread())
        .subscribe {
            println(Thread.currentThread().name)
            println(it)
        }
}

Flowable

Flowable可以看成Observable新的實現(xiàn),他支持背壓,而他的API和Observable相似,在最后會介紹背壓。

流式調(diào)用

我們已經(jīng)熟悉了Java Stream的好處,所以在這里簡單看下rxjava的實現(xiàn),用法都一樣,如下,創(chuàng)建集合"a","b","c","d"。

  • map將所有item前添加字符"1"。
  • filter將b結(jié)尾的數(shù)據(jù)過濾掉。
  • skip忽略前n個數(shù)據(jù)。
fun main() {
    Flowable.fromIterable(mutableListOf("a","b","c","d"))
        .map { "1${it}" }
        .filter { !it.endsWith("b") }
        .skip(1)
        .subscribe {
            println(it)
        }
}

所以最后收到的消息將是 1c、1d。

當(dāng)然他提供的這類API非常之多,就不介紹了。

背壓

背壓指的是遇到被觀察者發(fā)送的消息太快,至于它的訂閱者不能及時處理數(shù)據(jù),而我們可以提供一種告訴被觀察者遇到這種情況的策略。

這種場景有個前提條件,被觀察者和訂閱者在不同線程。

背壓策略被定義在BackpressureStrategy,有五種。

MISSING

通過create方法創(chuàng)建的Flowable沒有指定背壓策略,不會對通過OnNext發(fā)送的數(shù)據(jù)做緩存或丟棄,需要下游通過背壓操作符制定策略。

ERROR

如果緩存池數(shù)據(jù)超限,則拋出異常。

BUFFER

可以無限制添加數(shù)據(jù)。

DROP

如果緩存池滿了,則丟棄。

LATEST

僅保留最新的onNext值,如果下游無法跟上,則覆蓋之前的值。

如下,我們使用BUFFER策略,默認的緩存池大小是128,可以通過System.setProperty("rx3.buffer-size","5")指定,而這個策略會導(dǎo)致只有緩存池不滿的情況下,才會生產(chǎn)數(shù)據(jù)并發(fā)送給訂閱者。

fun main() {
    System.setProperty("rx3.buffer-size","5")
    Observable.interval(1,TimeUnit.MILLISECONDS)
        .toFlowable(BackpressureStrategy.BUFFER)
        .map { User(1) }
        .observeOn(Schedulers.newThread())
        .subscribe {
            Thread.sleep(1000)
            println("hander $it")
        }
    Thread.sleep(100000)
}

而如果我們改成DROP,那么最終只有5條數(shù)據(jù)被消費,其他全部丟棄。

fun main() {
    System.setProperty("rx3.buffer-size","5")
    Observable.range(1,999)
        .toFlowable(BackpressureStrategy.DROP)
        .map { User(1) }
        .observeOn(Schedulers.newThread())
        .subscribe {
            Thread.sleep(1000)
            println("hander $it")
        }
    Thread.sleep(100000)
}

其他就不做demo了。

以上就是Kotlin下Rxjava的基礎(chǔ)用法及流式調(diào)用示例詳解的詳細內(nèi)容,更多關(guān)于Kotlin Rxjava的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • 詳解Android Ashmem匿名共享內(nèi)存

    詳解Android Ashmem匿名共享內(nèi)存

    這篇文章主要介紹了Android Ashmem匿名共享內(nèi)存的相關(guān)資料,幫助大家更好的理解和學(xué)習(xí)使用Android開發(fā),感興趣的朋友可以了解下
    2021-04-04
  • Android實現(xiàn)帶頁面切換的鎖屏功能

    Android實現(xiàn)帶頁面切換的鎖屏功能

    這篇文章主要為大家詳細介紹了Android實現(xiàn)帶頁面切換的鎖屏功能,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2018-06-06
  • android實現(xiàn)Uri獲取真實路徑轉(zhuǎn)換成File的方法

    android實現(xiàn)Uri獲取真實路徑轉(zhuǎn)換成File的方法

    這篇文章主要介紹了android實現(xiàn)Uri獲取真實路徑轉(zhuǎn)換成File的方法,涉及Android操作路徑的相關(guān)技巧,需要的朋友可以參考下
    2015-05-05
  • Kotlin利用Regex如何構(gòu)建正則表達式詳解

    Kotlin利用Regex如何構(gòu)建正則表達式詳解

    正則表達式,又稱規(guī)則表達式。下面這篇文章主要給大家介紹了關(guān)于Kotlin利用Regex構(gòu)建正則表達式的相關(guān)資料,文中通過示例代碼介紹的非常詳細,對大家的工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面來一起看看吧。
    2017-12-12
  • Android開發(fā)常見錯誤小結(jié)

    Android開發(fā)常見錯誤小結(jié)

    這篇文章主要介紹了Android開發(fā)常見錯誤,實例分析了常見的Android開發(fā)中遇到的錯誤,對Android開發(fā)有一定參考借鑒價值,需要的朋友可以參考下
    2015-05-05
  • Android實現(xiàn)在列表List中顯示半透明小窗體效果的控件用法詳解

    Android實現(xiàn)在列表List中顯示半透明小窗體效果的控件用法詳解

    這篇文章主要介紹了Android實現(xiàn)在列表List中顯示半透明小窗體效果的控件用法,結(jié)合實例形式分析了Android半透明提示框的實現(xiàn)與設(shè)置技巧,需要的朋友可以參考下
    2016-06-06
  • Android源代碼倉庫及其管理工具Repo分析詳解

    Android源代碼倉庫及其管理工具Repo分析詳解

    本篇文章主要介紹了Android源代碼倉庫及其管理工具Repo分析詳解,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2018-01-01
  • Android使用WindowManager構(gòu)造懸浮view

    Android使用WindowManager構(gòu)造懸浮view

    這篇文章主要為大家詳細介紹了Android使用WindowManager構(gòu)造懸浮view的具體方法,感興趣的小伙伴們可以參考一下
    2016-05-05
  • Android自定義按周簽到打卡功能實例代碼

    Android自定義按周簽到打卡功能實例代碼

    這篇文章主要給大家介紹了關(guān)于Android自定義實現(xiàn)按周簽到打卡功能的相關(guān)資料,文中通過示例代碼介紹的非常詳細,對各位Android開發(fā)者們具有一定的參考學(xué)習(xí)價值,需要的朋友們下面來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-06-06
  • Android的廣播Receiver動態(tài)注冊和靜態(tài)注冊示例

    Android的廣播Receiver動態(tài)注冊和靜態(tài)注冊示例

    本篇文章主要介紹了Android的廣播Receiver動態(tài)注冊和靜態(tài)注冊示例,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-02-02

最新評論

木兰县| 潜山县| 松原市| 漾濞| 建宁县| 镇远县| 元氏县| 武冈市| 宾川县| 淮南市| 庆元县| 临沧市| 清涧县| 潞西市| 织金县| 惠来县| 榆树市| 邢台县| 井陉县| 二手房| 元朗区| 安龙县| 綦江县| 濮阳市| 三台县| 信丰县| 通化县| 吴忠市| 云林县| 山阴县| 蓬安县| 蚌埠市| 武强县| 从化市| 巴林右旗| 翁牛特旗| 仪陇县| 利津县| 哈巴河县| 郸城县| 晋城|