java - 从 java.lang.Observable 迁移到 RxJava

标签 java android rx-java

我正在开发一个带有购物车的 Android 应用程序。 Cart 对象扩展了 java.lang.Observable,因此如果有任何更改,它们会立即保存到磁盘,并且徽章图标也可以更新。

public class Cart extends Observable{

    private Set<Product> products;

    public Cart(){
        products = new HashSet<>();
    }

    public Cart(Collection<Product> products){
        this.products = new HashSet<>(products);
    }

    public int getTotalItems() {
        return products.size();
    }

    public void clear(){
        products.clear();
        setChanged();
        notifyObservers();
    }

    public void addProduct(Product product){
        products.add(product);
        setChanged();
        notifyObservers();
    }

    public void removeProduct(Product product){
        products.remove(product);
        setChanged();
        notifyObservers();
    }

    public void updateProduct(Product product){
        products.remove(product);
        products.add(product);
        setChanged();
        notifyObservers();
    }

    public List<Product> getProducts() {
        return new ArrayList<>(products);
    }
}

使用示例

public class MainActivity extends BaseActivity implements Observer {
    Cart mCart;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        ButterKnife.bind(this);

        getApp().getCart().addObserver(this);
        setCartItemsCount(getApp().getCart().getTotalItems());

        //...
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        if (getApp().getCart() != null) {
            getApp().getCart().deleteObserver(this);
        }
    }

    @Override
    public void update(Observable observable, Object data) {
        if (observable instanceof Cart) {
            setCartItemsCount(((Cart) observable).getTotalItems());
        }
    }
}

我想将此代码迁移到 RxJava,但我不清楚如何去做。根据我的阅读,我应该使用 BehavioralSubject 但我不知道如何使我读到的示例适应我的场景。

如果有一些指导或示例,我将不胜感激。

最佳答案

我做了一些小例子可以帮助你理解这个想法。 我用过这个库https://github.com/trello/RxLifecycle ,我也推荐你用这个http://google.github.io/dagger/

public class MainActivity extends RxActivity {

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    final CartPresenter cartPresenter = new CartPresenter();
    final TextView counterTextView = (TextView) findViewById(R.id.counter);
    final Button button = (Button) findViewById(R.id.button2);

    RxView.clicks(button)
            .subscribe(new Action1<Void>() {
                @Override
                public void call(Void aVoid) {
                    cartPresenter.getCardModel().addProduct(new Random().nextInt(100));
                }
            });

    cartPresenter.getCardObservable()
            .compose(this.<CartPresenter.CardModel>bindToLifecycle())
            .subscribe(new Action1<CartPresenter.CardModel>() {
                @Override
                public void call(CartPresenter.CardModel cardModel) {
                    counterTextView.setText(String.valueOf(cardModel.getProducts().size()));
                }
            });
}
}

一种对于初学者来说更容易理解的解决方案

public class CartPresenter {

    private final PublishSubject<CardModel> dataChangedSubject = PublishSubject.create();
    private final Observable<CardModel> cardObservable;
    private final CardModel cardModel;

    public CartPresenter() {
        cardModel = new CardModel();

        this.cardObservable = dataChangedSubject.startWith(cardModel)
                .flatMap(new Func1<CardModel, Observable<CardModel>>() {
                    @Override
                    public Observable<CardModel> call(CardModel cardModel) {
                        return Observable.just(cardModel);
                    }
                });
    }

    public CardModel getCardModel() {
        return cardModel;
    }

    @NonNull
    public Observable<CardModel> getCardObservable() {
        return cardObservable;
    }

    class CardModel {
        final private Set<Integer> products;

        public CardModel() {
            this.products = new HashSet<>();
        }

        public void addProduct(Integer integer) {
            products.add(integer);
            dataChangedSubject.onNext(this);
        }

        public Set<Integer> getProducts() {
            return products;
        }
    }
}

对于一些更高级的用户

public class CartPresenter {

    private final PublishSubject<CardModel> dataChangedSubject = PublishSubject.create();
    private final Observable<CardModel> cardObservable;
    private final CardModel cardModel;

    public CartPresenter() {
        cardModel = new CardModel();

        this.cardObservable = Observable.just(cardModel)
                .compose(new Observable.Transformer<CardModel, CardModel>() {
                    @Override
                    public Observable<CardModel> call(final Observable<CardModel> cardModelObservable) {
                        return dataChangedSubject.switchMap(new Func1<Object, Observable<? extends CardModel>>() {
                            @Override
                            public Observable<? extends CardModel> call(Object o) {
                                return cardModelObservable;
                            }
                        });
                    }
                });

    }

    public CardModel getCardModel() {
        return cardModel;
    }

    @NonNull
    public Observable<CardModel> getCardObservable() {
        return cardObservable;
    }

    class CardModel {
        final private Set<Integer> products;

        public CardModel() {
            this.products = new HashSet<>();
        }

        public void addProduct(Integer integer) {
            products.add(integer);
            dataChangedSubject.onNext(null);
        }

        public Set<Integer> getProducts() {
            return products;
        }
    }
}

关于java - 从 java.lang.Observable 迁移到 RxJava,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36839604/

相关文章:

java - 在 WEB-INF 文件夹下包含 JSP 文件

java - 用于不同列表和对象的多个适配器或一个适配器 - 代码性能

android - RxJava2 : How to get a dedicated background thread for work

android - token 语法错误,删除这些 token - R.java

java - 如何将 RxJava combineLatest 运算符与超过 9 个可观察对象一起使用

Spring 5 Web 响应式(Reactive)编程 - 从流数据的 Spring 响应式(Reactive) Controller 解码 JSON 时出现 WebClient ClassCastException

java - PersistenceUnitUtil 中 isLoaded(Object) 方法的用法

java - 模型映射器计算

java - Android Gradle 应用程序 :DexDebug error Parse. com

android - 没有前景的应用程序间通信的最佳方法?