欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Java技巧分享之利用RxJava打造可觀測數(shù)據(jù)RxLiveData

 更新時間:2023年06月09日 15:22:24   作者:樂征skyline  
這篇文章主要來和大家分享一個Java技巧,那就是利用RxJava打造可觀測數(shù)據(jù)RxLiveData,文中的示例代碼講解詳細,感興趣的小伙伴可以了解一下

1. 問題場景

在實際工作中,我們經(jīng)常需要在不同類對象之間、不同模塊之間共享數(shù)據(jù),而這些數(shù)據(jù)通常是可改動的,那么就可能發(fā)生一個問題:當數(shù)據(jù)變動時,相關(guān)對象或模塊并不知道,沒有及時更新數(shù)據(jù)。這時候,我們希望數(shù)據(jù)改變時可以通知其他模塊同步更新,實現(xiàn)一個類似數(shù)據(jù)之間聯(lián)動的效果。最容易想到的應該就是監(jiān)聽回調(diào)的觀察者模式,下面給出一種以前見過的、不太優(yōu)雅的實現(xiàn):

class User {
    //...... Java Bean 的字段略
}
interface Listener {
    void onUserUpdated(User user);
}
class UserManager {
    private static UserManager manager = new UserManager();
    private UserManager() {
    }
    public static UserManager getInstance() {
        return manager;
    }
    private User user;
    private List<Listener> listeners = new LinkedList<>();
    public void addUserListener(Listener listener) {
        listeners.add(listener);
    }
    public void removeUserListener(Listener listener) {
        listeners.remove(listener);
    }
    public User getUser() {
        return user;
    }
    public void setUser(User user) {
        this.user = user;
        for (Listener listener : listeners) {
            listener.onUserUpdated(this.user);
        }
    }
}

這種方式有以下缺點:

  • 不具備復用性(每次添加新的數(shù)據(jù)都要把回調(diào)監(jiān)聽重新實現(xiàn)一遍);
  • 增加內(nèi)存溢出的風險(調(diào)用addUserListener的人可能忘記調(diào)用removeUserListener);
  • setter方法的污染(做了多余的事情)。

面對這樣的問題,RxJava、JDK中的Observable和Flow API還有Android里的LiveData都給出了可用的實現(xiàn)方式,在實際開發(fā)中,感覺并不是那么方便。而本文要介紹的是我利用RxJava打造一個更加方便的可觀測對象工具類--RxLiveData(代碼見最底部)。

2. 使用示例

先來看一個比較短的完整示例:

/* 測試用的 Java Bean 數(shù)據(jù)類*/
class User {
    //...... Java Bean 的字段略
}
/* 一個單例 */
class UserManager {
    private static final UserManager manager = new UserManager();
    private UserManager() {
    }
    public static UserManager getInstance() {
        return manager;
    }
    private final RxLiveData<User> userData = new RxLiveData<>();
    public RxLiveData<User> getUserData() {
        return userData;
    }
}
class A {
    public void init() {
        //訂閱可觀測對象,使得數(shù)據(jù)發(fā)生改變時可以被回調(diào)
        UserManager.getInstance().getUserData().getObservable()
                .subscribe((User user) -> {//使用lambda版
                    update(user);// 每次用戶信息改變,這里會被調(diào)用
                });
        update(UserManager.getInstance().getUserData().getValue());
    }
    private void update(User user) {
        System.out.println("user changed");
    }
}
class B{
    public B() {
        UserManager.getInstance().getUserData().getObservable().subscribe(this::update);//方法引用版
    }
    private void update(User user) {
        System.out.println("user changed");
    }
}
public class Main {
    public static void main(String[] args) throws InterruptedException {
        A a = new A();
        a.init();
        B b = new B();
        //更新UserManager中的數(shù)據(jù),這時候A和B中的對應方法會被調(diào)用
        UserManager.getInstance().getUserData().postData(new User());
    }
}

這里模擬UserManager的數(shù)據(jù)在AB類的對象之間共享,當UserManager的內(nèi)容發(fā)生改變時,可以通知到AB,執(zhí)行相應操作。

這時如果還想給UserManager增加一個數(shù)據(jù),例如一個long類型的time,只需要按照下面這樣添加一個屬性和一個getter方法就可以了:

private final RxLiveData<Long> timeData = new RxLiveData<>();
public RxLiveData<Long> getTimeData() {
    return timeData;
}

如果是在Android應用開發(fā)中,還可以借助RxAndroid和RxLifecycle的功能,來控制回調(diào)的執(zhí)行線程并在界面銷毀時取消訂閱,例如:

userManager.getUserData().getObservable()
        .compose(bindUntilEvent(ActivityEvent.DESTROY))//指定在onDestroy回調(diào)時取消訂閱
        .observeOn(AndroidSchedulers.mainThread())//指定主線程
        .subscribe(user -> {
        }, Throwable::printStackTrace);

3. 主要方法介紹

3.1 getObservable 方法

方法簽名public Observable<T> getObservable()

這個方法用于獲取RxJava的Observable,進而對數(shù)據(jù)進行訂閱,還可以得到RxJava相關(guān)功能的支持(例如,Stream 操作,指定線程,控制生命周期等等)。

3.2 postData 方法

方法簽名public void postData(T value)

這個方法用于更新數(shù)據(jù)。它會更新存在在當前RxLiveData對象中的數(shù)據(jù),并通過RxJava的ObservableEmitter觸發(fā)觀察者的回調(diào)。

注意:當參數(shù)為null時,由于RxJava會對null拋出異常,所以這里的實現(xiàn)方式是在判斷為null的時候只存儲數(shù)據(jù),不觸發(fā)觀察者的回調(diào)。

3.3 getValue 方法

方法簽名public T getValue()

這個方法僅用于獲得存在在當前RxLiveData中的數(shù)據(jù)。

3.4 optValue 方法

方法簽名public Optional<T> optValue()

getValue方法的Optional版本。

4. 完整實現(xiàn)

import io.reactivex.rxjava3.core.Observable;//如果用的是RxJava2的請改為該版本的包名
import io.reactivex.rxjava3.core.ObservableEmitter;
import io.reactivex.rxjava3.disposables.Disposable;
import java.util.Optional;
public class RxLiveData<T> {
    private final Observable<T> observable;
    private Disposable disposable;
    private T value;
    private ObservableEmitter<T> emitter;
    public RxLiveData() {
        observable = Observable
                .create((ObservableEmitter<T> emitter) -> this.emitter = emitter)
                .publish()
                .autoConnect(0, disposable -> this.disposable = disposable);
    }
    public Observable<T> getObservable() {
        return observable;
    }
    public void postData(T value) {
        this.value = value;
        if (emitter != null && value != null) {
            emitter.onNext(value);
        }
    }
    public T getValue() {
        return value;
    }
    public Optional<T> optValue() {
        return Optional.ofNullable(value);
    }
}

到此這篇關(guān)于Java技巧分享之利用RxJava打造可觀測數(shù)據(jù)RxLiveData的文章就介紹到這了,更多相關(guān)Java RxJava可觀測數(shù)據(jù)內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 基于SpringBoot實現(xiàn)驗證碼功能的代碼及思路

    基于SpringBoot實現(xiàn)驗證碼功能的代碼及思路

    SpringBoot技術(shù)是目前市面上從事JavaEE企業(yè)級開發(fā)過程中使用量最大的技術(shù),下面這篇文章主要給大家介紹了如何基于SpringBoot實現(xiàn)驗證碼功能的相關(guān)資料,文中通過代碼介紹的非常詳細,需要的朋友可以參考下
    2024-07-07
  • Spring中RedisTemplate使用方法詳解

    Spring中RedisTemplate使用方法詳解

    Spring封裝了一個比較強大的模板,也就是redisTemplate,方便在開發(fā)的時候操作Redis緩存,這篇文章主要給大家介紹了關(guān)于Java中RedisTemplate使用方法的相關(guān)資料,需要的朋友可以參考下
    2023-12-12
  • 分析講解SpringMVC注解配置如何實現(xiàn)

    分析講解SpringMVC注解配置如何實現(xiàn)

    這篇文章主要介紹了本文要介紹用注解方式代替web.xml與SpringMVC的配置文件,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2022-05-05
  • dubbo如何設置連接zookeeper權(quán)限

    dubbo如何設置連接zookeeper權(quán)限

    這篇文章主要介紹了dubbo如何設置連接zookeeper權(quán)限問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2024-05-05
  • java保證一個方法只能執(zhí)行一次的問題

    java保證一個方法只能執(zhí)行一次的問題

    這篇文章主要介紹了java保證一個方法只能執(zhí)行一次的問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2023-08-08
  • SpringBoot項目yml配置文件不自動提示解決方案

    SpringBoot項目yml配置文件不自動提示解決方案

    這篇文章主要介紹了SpringBoot項目配置文件.yaml/.yml文件編寫時沒有自動提示的解決方案,文章通過圖文結(jié)合的方式給大家講解的非常詳細,需要的朋友可以參考下
    2024-06-06
  • 前端如何調(diào)用后端接口進行數(shù)據(jù)交互詳解(axios和SpringBoot)

    前端如何調(diào)用后端接口進行數(shù)據(jù)交互詳解(axios和SpringBoot)

    一般來講前端不會給后端接口,而是后端給前端接口的情況比較普遍,下面這篇文章主要給大家介紹了關(guān)于前端如何調(diào)用后端接口進行數(shù)據(jù)交互的相關(guān)資料,文中通過實例代碼介紹的非常詳細,需要的朋友可以參考下
    2023-03-03
  • 解析HashMap中的put方法執(zhí)行流程

    解析HashMap中的put方法執(zhí)行流程

    在Java集合中,HashMap的重要性不言而喻,作為一種存儲鍵值對的數(shù)據(jù)結(jié)構(gòu),它在日常開發(fā)中有著非常多的應用場景,也是面試中的高頻考點,本篇文章就來分析一下HashMap集合中的put方法
    2021-12-12
  • 關(guān)于解決雪花算法生成的ID傳輸前端后精度丟失問題

    關(guān)于解決雪花算法生成的ID傳輸前端后精度丟失問題

    這篇文章主要介紹了關(guān)于解決雪花算法生成的ID傳輸前端后精度丟失問題,雪花算法生成的ID傳輸?shù)角岸藭r,會出現(xiàn)后三位精度丟失,本文提供了解決思路,需要的朋友可以參考下
    2023-03-03
  • java中斷機制實例講解

    java中斷機制實例講解

    這篇文章主要介紹了java中斷機制實例講解,用了風趣幽默的講法,有對這方面不太懂的同學可以研究下
    2021-01-01

最新評論