2017-10-04 66 views
1

在实施上,建议治疗Android框架作为一个插件,不会泄露任何Android意识到依赖到演示层MVP模式Android的“干净”架构的努力。使用rxjava,如果我有被设计为“推”的数据到视图层演示者本人可能希望有这样的逻辑:在RxJava上使用Android上的清洁MVP:如何让演示者在使用UI线程的同时观察任何Android知识?

public interface SearchPresenter { 

    interface ViewLayer { 
    void updateResults(List<SearchResult> searchResults) 
    } 
    void bind(ViewLayer viewLayer); 
    void unbind(); 
} 

public class SearchPresenterImpl implements SearchPresenter { 

    ViewLayer viewLayer; 
    CompositeDisposable compositeDisposable; 

    @Override 
    public void bind(ViewLayer viewLayer) { 
     this.viewLayer = viewLayer; 

     compositeDisposable = new CompositeDisposable(); 
     compositeDisposable.add(
      searchInteractor.getSearchResults() 
      .subscribeOn(Schedulers.io()) 
      .observeOn(AndroidSchedulers.mainThread()) 
      .subscribe(this::refreshView)); 

} 

private void refreshView(List<SearchResult> searchResults) { 
    //send the results back to the view layer to update a RecyclerView  
    viewLayer.updateResults(searchResults) 
} 

@Override 
public void unbind() { 
    compositeDisposable.dispose(); 
} 

然而,通过观察“AndroidSchedulers.mainThread()”这个力依赖于:

import io.reactivex.android.schedulers.AndroidSchedulers 

在这一点上,我的主持人现在知道关于android并且被绑定到它;这是我想避免的。

有什么建议的方法来处理这个问题,这样的结果是保证交付给ViewLayer对Android的UI(主)线程同时演示保持上的任何Android的相关不依赖?

+0

也许ViewLayer接口需要像'可观察getThread()一些方法;'? – 0X0nosugar

回答

1

AndroidSchedulers.mainThread()采用了Android的代码在主线程调度的行为,不直接在您的演示使用。 相反,你可以重构演示者采取的调度程序在其构造,在生产代码中使用的常规AndroidSchedulers.mainThread()Schedulers.io(),在测试时,可以只发送Schedulers.trampoline()Schedulers.immediate()

在这个例子中看到这种模式:https://github.com/riggaroo/GithubUsersSearchApp/blob/master/app/src/main/java/za/co/riggaroo/gus/presentation/search/UserSearchPresenter.java

及其测试类的位置: https://github.com/riggaroo/GithubUsersSearchApp/blob/8b83095d7a2cc8f3cb69a945224ab4c37cf54a37/app/src/test/java/za/co/riggaroo/gus/presentation/search/UserSearchPresenterTest.java

+0

当然。恰恰是我失踪的那部分。 – JohnRock

0

正如在前面的回答指出,你可以在Presenter构造注入Scheduler但至少有两个以上的可能性。

  1. 您可以直接注入到Schedulerinteractor然后你不需要做任何操纵presenter。然后,在测试中,你可以嘲笑你的interactor,完全忘了在测试中大约rxjava依赖。

  2. 您可以使用RxJavaPluginsRxAndroidPlugins覆盖调度在测试中,如果你觉得这是对你罚款,以保持AndroidSchedulers的作用因子。

所以定义(科特林):

object RxJavaPluginHelper { 

    fun setup(scheduler: Scheduler = Schedulers.trampoline()) { 
     RxAndroidPlugins.setInitMainThreadSchedulerHandler { _ -> scheduler } 
     RxJavaPlugins.setComputationSchedulerHandler { scheduler } 
     RxJavaPlugins.setIoSchedulerHandler { scheduler } 
     RxJavaPlugins.setNewThreadSchedulerHandler { scheduler } 
     RxJavaPlugins.setSingleSchedulerHandler { scheduler } 
    } 

    fun teardown() { 
     RxAndroidPlugins.reset() 
     RxJavaPlugins.reset() 
    } 
} 

然后用

companion object { 
     @BeforeClass 
     @JvmStatic 
     fun setup() { 
      RxJavaPluginHelper.setup() 
     } 

     @AfterClass 
     @JvmStatic 
     fun teardown() { 
      RxJavaPluginHelper.teardown() 
     } 
    } 

个人而言,我不会去除从发言这条线作战,作为一个整体的想法背后的去除Android进口Presenter是为了使它可以移植到不同的平台,但由于它不太可能发生,我会把它当作好的。

相关问题