正在加载数据Reactive / non-reactive,LiveData,RxJava

时间:2017-10-06 12:37:22

标签: android rx-java2 android-architecture-components android-livedata

我首先要说我已经阅读了一百万个博客,观看了一千个视频,让我对这个页面感到更加困惑。在输入所有这些内容时,莫名其妙地帮助我工作了一些事情。

TL; DR 主要问题是如何为UI层反应性地(使用后台线程)检索数据并且通常(在方法中内联)用于已在后台线程上调用方法的业务层方法。做你的回购&& Dao需要多种方法来执行相同的查询吗?

@Query("Select * from Product WHERE Product.ProductId = :id")
ProductDb getForId(Integer id);

@Query("Select * from Product WHERE Product.ProductId = :id")
LiveData<ProductDb> getForIdLive(Integer id);

@Query("Select * from Product WHERE Product.ProductId = :id")
Maybe<ProductDb> getForIdRx(Integer id);

使用MVVM架构。新Android架构组件中的ViewModel实现可以解决生命周期问题,因此我们可以使用它。

使用Room数据库组件实现的数据库 - 所有设置都运行良好,它是如何在我的应用程序的各个层检索困扰我的数据。

我们将举一个通过Id从数据库中检索产品的简单示例。

LiveData 如果您只是希望UI中的数据显示,则此选项似乎很好。 您的活动或片段创建ViewModel,设置一个等待数据的Observer。

// get an instance of the viewmodel
mMyViewModel = ViewModelProviders.of(this).get(MyViewModel.class);

// Setup an observer on the Product.  This will tell us when one is loaded.
final Observer<Product> productObserver = new Observer<Product>() {
    @Override
    public void onChanged(Product product) {
        doSomethingWithProduct(product);
    }
};

然后可以通过调用ViewModel中的方法来加载产品,响应是spat out to doSomethingWithProduct()我们在观察者中设置

mMyViewModel.getProductById(productId).observe(this,productObserver);

ViewModel有一个方法

public LiveData<Product> getProductById(int id) {
    return mReferenceDataRepository.loadProductById(id);
}

存储库有一个非常相似的方法

public LiveData<Product> loadProductById(int id) {
    return mProductDao.loadProductById(id);
}

最后是房间架构的Dao作为进行实际数据库检索的方法。

@Query("SELECT * from Product WHERE ProductId = :id")
LiveData<Product> loadProductById(int id);

我们正在使用从数据库到观察者的LiveData,一切都很有效。因为Dao是LiveData,所以检索是在后台线程上完成的,后台线程负责处理由房间吐出的ANR。为了检索简单显示的数据,这条路线似乎很完美。

然而,并非一切都与UI有关!

应用程序比这更复杂。我将库存商品添加到库存中,并根据存储在产品/位置等中的多个业务规则,我可能需要将其置于隔离区或拒绝它。

  • 活动不应该实施这些业务规则,其工作是 只需与用户沟通,另外可能有几个活动可以添加库存项目

  • ViewModel不应该实现这些业务规则,这是相同的规则 可能需要多个活动。

  • 知识库不应该实现这些业务规则 - 应该吗?

我在StockItemBL(业务层)中实施这些规则。 AddItemToStock方法。

现在我需要从数据库加载产品,但我不想要LiveData&lt;&gt;。我不想以反应方式加载产品,我不需要在BusinessLayer中做出反应,当您需要加载多个Db表来执行业务逻辑时,它不会起作用。我只想要一个很好的旧时尚

Product p = mReferenceDataRepository.loadProductById(productId);
Location l = mReferenceDataRepository.loadLocationById(locationId);

if (p.getQuarantine())....

if (l.getIsQuarantine())....

但该方法返回一个LiveData,而不仅仅是POJO产品 我现在需要在存储库中使用另一种方法吗?

我也在同样的方面看过RxJava 你可以从Dao返回一个Maybe,事实上,Rx更容易管理异常。但它有同样的问题 - 你需要在你的存储库和Dao中使用单独的方法。

实际上,使用存储库的原因是您可以切换实现。如果您的方法暴露了LiveData或Maybe,那么您真的可以轻松地切换实现吗?

0 个答案:

没有答案