为什么要在主线程上订阅?

安德鲁

试图从此资源中找出一些东西:https : //www.raywenderlich.com/384-reactive-programming-with-rxandroid-in-kotlin-an-introduction

我遇到一个问题:为什么我应该在主线程而不是Schedulers.io()中调用subscribeOn()?

当我这样订阅时,我的应用程序冻结了几秒钟,并且丢了帧。

searchTextObservable
                .subscribeOn(Schedulers.io())
                .map { cheeseSearchEngine.search(it) }
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe {
                    showResult(it)
                }

丢帧屏幕

然后我订阅了主线程,并在Schedulers.io()中观察了它(我也不明白为什么要那样做)应用程序完全没有冻结。

searchTextObservable
                .subscribeOn(AndroidSchedulers.mainThread())
                .observeOn(Schedulers.io())
                .map { cheeseSearchEngine.search(it) }
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe {
                    showResult(it)
                }

谁能解释一下为什么这样工作吗?

编辑

// 1
private fun createTextChangeObservable(): Observable<String> {
  // 2
  val textChangeObservable = Observable.create<String> { emitter ->
    // 3
    val textWatcher = object : TextWatcher {

      override fun afterTextChanged(s: Editable?) = Unit

      override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) = Unit

      // 4
      override fun onTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {
        s?.toString()?.let { emitter.onNext(it) }
      }

    }

    // 5
    queryEditText.addTextChangedListener(textWatcher)

    // 6
    emitter.setCancellable {
      queryEditText.removeTextChangedListener(textWatcher)
    }
  }

  // 7
  return textChangeObservable
}
汉斯·沃斯特

subscribeOn vs.observeOn

subscriptionOn将在给定的Scheduler上调用Observable的create方法。多少次使用subscribeOn都没有关系。Source-observable的第一个subscriptionOn(链中的第一个)始终获胜。

watchOn将在操作员之间切换线程。当上游在线程X上发出一个值时,它将在observeOn-Operator中从给定的调度程序切换到线程Y。现在,observeOn下面的所有内容都将在线程Y中进行处理。

提供的示例1的最佳猜测:使用subscriptionOn将在Schedulers#io上调用Observable#create。将在Scheduler#io的此线程上调用create-lambda中的所有内容。侦听器回调(onTextChanged)实际上可以在另一个线程上发生。在这种情况下,它是UI-Thread,因为它是某种UI元素。现在,将从UI线程(emitter.onNext(it))调用onNext。该值将在UI-Thread(.map {cheeseSearchEngine.search(it))上发送给#map运算符,而cheeseSearchEngine#search将阻止UI-Thread。

示例2:用作第一个运算符“ .subscribeOn(AndroidSchedulers.mainThread())”。实际上这没有任何效果,因为您已经在UI-Thread中。在这种情况下,将从AndroidSchedulers#mainThread调用create-lambda。就在Example1中,onNext也会在UI-Thread上发出,因为UI会触发onTextChanged-Event。然后将值通过observeOn(Schedulers.io())放入。来自observeOn-point的所有内容都将在Schedulers#io-Thread上执行。当map执行某些HTTP请求(或某种长时间运行的IO)时,这将不会阻止ui。映射完成并向下游发出下一个值后,下一个observeOn(AndroidSchedulers.mainThread())将切换回UI-Thread。因此,由于您位于UI线程上,因此现在可以安全地更改subscription-lambda中的UI。

摘要:使用subscriptionOn只会在给定的Scheduler-Thread上调用create lambda。create中已注册侦听器的回调可能在另一个线程上发生。这就是为什么Example1将阻止UI-Thread而Example2将不会阻止UI-Thread的原因。

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Java

为什么ForkJoinPool ::的invoke()阻塞主线程?

来自分类Java

为什么主线程不被终止

来自分类Java

为什么invokeLater的主线程中执行?

来自分类Java

为什么工作的AsyncTask主线程?

来自分类Java

Java:为什么主线程没有进行?

来自分类Java

为什么此Future的方法阻塞了主线程?

来自分类Dev

RXSwift不订阅主线程

来自分类Dev

为什么将UIViewController释放在主线程上?

来自分类Dev

为什么CompletableFuture的thenAccept()无法在主线程上运行

来自分类Dev

为什么WPF的Dispatcher.Invoke在主线程上运行时不会导致死锁?

来自分类Dev

是否需要在主线程上绘制MTKView或CAMetalLayer?

来自分类Dev

为什么映像不会在主线程上加载?

来自分类Dev

为什么主线程还调用线程池的execute()方法?

来自分类Dev

为什么主线程在这里没有被抢占?

来自分类Dev

为什么Future会阻塞主线程?

来自分类Dev

为什么主线程没有关机方法

来自分类Dev

为什么任务在主线程中运行?

来自分类Dev

为什么要在主线程上休眠才能运行Camel示例

来自分类Dev

Android:Volley:为什么必须从主线程调用volley imageLoader?

来自分类Dev

为什么我的代码在主线程上运行?

来自分类Dev

为什么我的NSOperationQueue在主线程上运行?

来自分类Dev

需要在主线程上执行什么

来自分类Dev

为什么在主线程中收到CMException错误?

来自分类Dev

为什么UIWebView的AVPlayerViewController不在主线程上运行?

来自分类Dev

为什么这个订阅会阻塞主线程?

来自分类Dev

为什么主线程等待后台线程完成

来自分类Dev

为什么在回调中线程变为主线程?

来自分类Dev

Kotlin:为什么 job.invokeOnCompletion() 块不在主线程上运行?

来自分类Dev

为什么队列不在主线程上更新?

Related 相关文章

  1. 1

    为什么ForkJoinPool ::的invoke()阻塞主线程?

  2. 2

    为什么主线程不被终止

  3. 3

    为什么invokeLater的主线程中执行?

  4. 4

    为什么工作的AsyncTask主线程?

  5. 5

    Java:为什么主线程没有进行?

  6. 6

    为什么此Future的方法阻塞了主线程?

  7. 7

    RXSwift不订阅主线程

  8. 8

    为什么将UIViewController释放在主线程上?

  9. 9

    为什么CompletableFuture的thenAccept()无法在主线程上运行

  10. 10

    为什么WPF的Dispatcher.Invoke在主线程上运行时不会导致死锁?

  11. 11

    是否需要在主线程上绘制MTKView或CAMetalLayer?

  12. 12

    为什么映像不会在主线程上加载?

  13. 13

    为什么主线程还调用线程池的execute()方法?

  14. 14

    为什么主线程在这里没有被抢占?

  15. 15

    为什么Future会阻塞主线程?

  16. 16

    为什么主线程没有关机方法

  17. 17

    为什么任务在主线程中运行?

  18. 18

    为什么要在主线程上休眠才能运行Camel示例

  19. 19

    Android:Volley:为什么必须从主线程调用volley imageLoader?

  20. 20

    为什么我的代码在主线程上运行?

  21. 21

    为什么我的NSOperationQueue在主线程上运行?

  22. 22

    需要在主线程上执行什么

  23. 23

    为什么在主线程中收到CMException错误?

  24. 24

    为什么UIWebView的AVPlayerViewController不在主线程上运行?

  25. 25

    为什么这个订阅会阻塞主线程?

  26. 26

    为什么主线程等待后台线程完成

  27. 27

    为什么在回调中线程变为主线程?

  28. 28

    Kotlin:为什么 job.invokeOnCompletion() 块不在主线程上运行?

  29. 29

    为什么队列不在主线程上更新?

热门标签

归档