Mosby MVI - 如何重用演示者

时间:2017-06-22 06:13:45

标签: android mosby

我的演示者看起来如下:

// I'm retaining the presenter in a singleton instances map and reuse them
// because they are loading data from the internet and this should be done once 
// per app start only
public static ArticlePresenter get(Article article)
{
    if (INSTANCES.containsKey(article.id()))
        return INSTANCES.get(article.id());
    ArticlePresenter instance = new ArticlePresenter();
    INSTANCES.put(article.id(), instance);
    return instance;
}

@Override
protected void bindIntents()
{
    ArrayList<Observable<ArticlePartialStateChanges>> observables = new ArrayList<>();

    observables.add(intent(ArticleView::loadArticleIntent)
            .doOnNext(article -> L.d("intent: loadArticleIntent"))
            .flatMap(article -> AndroInteractor.loadArticle(article)
                    .map(data -> (ArticlePartialStateChanges) new ArticlePartialStateChanges.Loaded(data))
                    .startWith(new ArticlePartialStateChanges.LoadingArticle(article))
                    .onErrorReturn(ArticlePartialStateChanges.LoadingArticleError::new)
                    .subscribeOn(Schedulers.io())
            )
    );

    Observable<ArticlePartialStateChanges> allIntents = Observable.merge(observables);
    ArticleViewState initialState = ArticleViewState.builder().build();
    Observable<ArticleViewState> stateObservable = allIntents
            .scan(initialState, this::viewStateReducer)
            .observeOn(AndroidSchedulers.mainThread());
    subscribeViewState(stateObservable, ArticleView::render);
}

我的片段loadArticleIntent如下所示:

@Override
public Observable<Article> loadArticleIntent()
{
    return Observable.just(article).doOnComplete(() -> L.d("Article loaded"));
}

结果

如果第一次创建片段,我会得到以下3项:

  1. 最初的事件
  2. 加载文章事件
  3. 已加载的文章或错误事件
  4. 如果再次创建片段,它将从地图中检索已存在的演示者,并将重用其中的最后一个已知状态。然后我得到以下:

    1. 上次加载的活动
    2. 最初的事件
    3. 加载文章事件
    4. 已加载的文章或错误事件
    5. 这并不完美,我需要将逻辑更改为仅发出最后一个已知状态(屏幕旋转后发生的相同行为)。

      我该怎么解决这个问题?

1 个答案:

答案 0 :(得分:2)

不要重复使用Presenter。这不是预期的方式。重复使用它们今天可能会起作用,但不能保证它将来也会起作用。

所以基本上你只想使用从业务逻辑中检索到的数据,对吧?基本上,您希望此部件预先加载数据AndroInteractor.loadArticle(article)。所以只需在app开始时调用它,而不是整个演示者。也许您使用一些内存/磁盘缓存库,或者只在BehaviorSubject内部使用AndroInteractor.loadArticle(article)。那个保存最新数据(如果有的话)。

所以你的问题只是一个“业务逻辑问题”/“缓存数据问题”而不是真正的“演示者”问题。因此,您应该在业务逻辑层解决此问题,即AndroInteractor.loadArticle(article),而不是保留整个Presenter。