Using clean MVP on android with RxJava: How can you keep the presenter free of any android knowledge while still observing on the UI thread?

六月ゝ 毕业季﹏ 提交于 2019-12-04 09:46:12

AndroidSchedulers.mainThread() uses Android code to schedule actions on the main thread, don't use it directly in your presenter. instead You can refactor the presenter to take Schedulers in its constructor, in production code use the regular AndroidSchedulers.mainThread() and Schedulers.io(), in testing you can just send Schedulers.trampoline() or Schedulers.immediate() .

see this pattern in this example: https://github.com/riggaroo/GithubUsersSearchApp/blob/master/app/src/main/java/za/co/riggaroo/gus/presentation/search/UserSearchPresenter.java

and its test class here: https://github.com/riggaroo/GithubUsersSearchApp/blob/8b83095d7a2cc8f3cb69a945224ab4c37cf54a37/app/src/test/java/za/co/riggaroo/gus/presentation/search/UserSearchPresenterTest.java

As pointed in previous answer you can inject Scheduler in constructor of Presenter but there is at least two more possibilities.

  1. You can inject Scheduler directly to interactor and then you don't need to do any manipulation in presenter. Then in tests you can mock your interactor and completely forget about rxjava dependency in your tests.

  2. You can use RxJavaPlugins and RxAndroidPlugins to override schedulers in tests if you feel that it is fine for you to keep AndroidSchedulers in interactors.

So define (Kotlin):

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()
    }
}

And then use

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

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

Personally I would not fight for removing this line from presenter, as whole idea behind removing Android imports from Presenter is to make it portable to different platforms, but since it is unlikely to happen I would treat it as ok.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!