【问题标题】:Rxjava, combineLatest with RxTextView memory leakRxjava, combineLatest 和 RxTextView 内存泄漏
【发布时间】:2018-09-21 15:31:52
【问题描述】:

我正在尝试将 combineLatest 与多个 RxTextViews 一起使用,并且我认为我正在正确处理我的 Disposables,但看起来我仍然存在内存泄漏。

val one = RxTextView.afterTextChangeEvents(one)
            val two = RxTextView.afterTextChangeEvents(two)
            val three = RxTextView.afterTextChangeEvents(three)
            val four = RxTextView.afterTextChangeEvents(four)
            val five = RxTextView.afterTextChangeEvents(five)

            val disposable = Observables.combineLatest(one, two, three, four, five) { oneEvent, twoEvent, threeEvent, fourEvent, fiveEvent ->
                 //combining happening with these strings: oneEvent.view().text.toString  }
                    .skip(1) 
                    .debounce(1000, TimeUnit.MILLISECONDS)
                    .observeOn(AndroidSchedulers.mainThread())
                    .subscribe {
                        //network call
                    }
            compositeDisposable.add(disposable)
        }

然后在我的onStop 中处理它。

override fun onStop() {
    super.onStop()
    if (!compositeDisposable.isDisposed) {
        compositeDisposable.dispose()
    }
}

我读到如果在 onNext() 方法中引用了某些视图,那么我认为可能会发生 NullPointerException。这是我得到的 NPE:

fatal Exception: java.lang.NullPointerException: view == null
       at com.jakewharton.rxbinding2.internal.Preconditions.checkNotNull(Preconditions.java:27)
       at com.jakewharton.rxbinding2.widget.RxTextView.afterTextChangeEvents(RxTextView.java:159)
       at MyFragment$setUpTextListeners$1.execute(MyFragment.kt:170)

这是我正在使用的片段:

private lateinit var viewModel: MyViewModel
private lateinit var binding: FragmentMyThingsBinding

private val compositeDisposable = CompositeDisposable()

override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {

    binding = FragmentMyThingsBinding.inflate(inflater, container, false)
    viewModel = ViewModelProviders.of(this).get(MyViewModel::class.java)
    binding.viewModel = viewModel

    //calls to kick off business logic

    return binding.root
}


override fun onStart() {
    super.onStart()

    setUpTextListeners()
}

override fun onStop() {
    super.onStop()
    if (!compositeDisposable.isDisposed) {
        compositeDisposable.dispose()
    }
}

private fun setUpTextListeners() {

    val one = RxTextView.afterTextChangeEvents(one)
    val two = RxTextView.afterTextChangeEvents(two)
    val three = RxTextView.afterTextChangeEvents(three)
    val four = RxTextView.afterTextChangeEvents(four)
    val five = RxTextView.afterTextChangeEvents(five)

    compositeDisposable.add(Observables.combineLatest(one, two, three, four, five) { oneEvent, twoEvent, threeEvent, fourEvent, fiveEvent ->
            //combine here using oneEvent.view().text.toString  }
            .skip(1)
            .debounce(1000, TimeUnit.MILLISECONDS)
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe {
                //network call
            })

    }
}

【问题讨论】:

    标签: android memory-leaks rx-java rx-kotlin rx-binding


    【解决方案1】:

    您传递给RxTextView.afterTextChangeEvents 的其中一个视图为空。有assert in that function,用于检查null 上的传入参数。

    而且这个问题与内存泄漏无关。

    编辑: 将合成视图属性更改为使用 binding.editText 解决了该问题。 (在cmets中讨论)

    【讨论】:

    • 没错。但这只是时不时发生,我无法确定确切的原因。有什么想法吗?
    • 你能提供MyFragment类的代码吗?需要调查它以帮助您。
    • 添加片段
    • 我还应该提到,我正在使用一个视图寻呼机,它为每个页面旋转该片段的newInstance。
    • 该代码是否正确val one = RxTextView.afterTextChangeEvents(one)?传递给函数one 的参数在哪里定义?
    猜你喜欢
    • 1970-01-01
    • 2015-11-06
    • 1970-01-01
    • 2023-03-18
    • 2020-08-02
    • 2017-02-13
    • 2015-04-04
    • 1970-01-01
    • 2010-12-02
    相关资源
    最近更新 更多