Понимание CompositeDisposable в RxJava + Kotlin

Я использую RxJava для проверки формы для проверки имени пользователя и пароля. Мой вариант использования довольно прост, если оба поля удовлетворяют соответствующему условию, а затем включите кнопку входа в систему, иначе отключите ее. следующий мой код.


    lateinit var subscriptions: CompositeDisposable
    private fun validateForm() {
        val emailObservable = viewBinding.detUserName.editText.textChangeEvents()
            .skipInitialValue()
            .map { isValidEmail(it.text) || isValidPhoneNumber(it.text) }
            .doOnDispose {
                Log.i("disposed", "emailObservable")
            }


        val passwordObservable = viewBinding.detPassword.editText.textChangeEvents()
            .skipInitialValue()
            .map { !TextUtils.isEmpty(it.text) }
            .doOnDispose {
                Log.i("disposed", "passwordObservable")
            }

        val disposable = Observable.combineLatest(emailObservable, passwordObservable,
            BiFunction<Boolean, Boolean, Boolean> { t1, t2 -> t1 && t2 }).subscribeOn(Schedulers.io())
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe {
                viewBinding.bLogin.isEnabled = it
            }
        subscriptions.add(disposable)
    }

fun isValidEmail(target: CharSequence): Boolean {
        return !TextUtils.isEmpty(target) && android.util.Patterns.EMAIL_ADDRESS.matcher(target).matches()
    }

    fun isValidPhoneNumber(target: CharSequence): Boolean {
        return !TextUtils.isEmpty(target) && Pattern.compile("(05|9665)[0-9]{8}").matcher(target).matches()
    }

Я подписка — это ссылка на объект CompositeDisposable, которую я создаю в onCreate и onResume (если она не создана или уже очищена/утилизирована) и размещаю ее в onStop()

Изменить

следующее является частью моего базового фрагмента

 override fun onResume() {
        super.onResume()
        createDisposable()
    }

    protected fun createDisposable() {
        if (!this::subscriptions.isInitialized) {
            subscriptions = CompositeDisposable()
        }
    }
   override fun onStop() {
        super.onStop()
        disposeAll()
    }

    protected fun disposeAll() {
        if (this::subscriptions.isInitialized) {
            subscriptions.clear()
        }
    }

фрагмент моего входа

override fun onResume() {
        super.onResume()
        validateForm()
    }

Впервые Observable.combineLatest работает нормально, но проблема в том, что когда приложение переходит в фоновый режим и возобновляет работу, оно больше не запускается. когда он перешел в фоновый режим, вызовы onStop() очищают композитный Disposable, удаляющий все одноразовые, когда он возобновляется, я снова добавляю новый экземпляр одноразовых объектов в композитный Disposable, но он не срабатывает. Я не могу найти способ исправить это, буду признателен за любые наводки.


person r4jiv007    schedule 28.08.2019    source источник
comment
вы звоните validateForm() снова, когда начинается активность?   -  person Linh    schedule 28.08.2019
comment
да, я делаю в onResume() @PhanVanLinh, пожалуйста, проверьте мои правки   -  person r4jiv007    schedule 28.08.2019
comment
Вы можете использовать rxbinding, который очень легко реализовать. См. фрагмент.   -  person Abu Noman    schedule 28.08.2019
comment
@AbuNoman, я использую то же самое, пожалуйста, проверьте мой код еще раз. его расширение kotlin предоставляется rxbinding, но я не думаю, что это проблема   -  person r4jiv007    schedule 28.08.2019


Ответы (1)


Инициализируйте CompositeDisposable во фрагменте входа в систему, добавьте все disposable к CompositeDisposable и очистите его onPause. Похоже:

private var subscriptions: CompositeDisposable = CompositeDisposable()

private fun validateForm() {
    val emailObservable = viewBinding.detUserName.editText.textChangeEvents()
        .skipInitialValue()
        .map { isValidEmail(it.text) || isValidPhoneNumber(it.text) }
        .doOnDispose {
            Log.i("disposed", "emailObservable")
        }


    val passwordObservable = viewBinding.detPassword.editText.textChangeEvents()
        .skipInitialValue()
        .map { !TextUtils.isEmpty(it.text) }
        .doOnDispose {
            Log.i("disposed", "passwordObservable")
        }

    val disposable = Observable.combineLatest(emailObservable, passwordObservable,
        BiFunction<Boolean, Boolean, Boolean> { t1, t2 -> t1 && t2 }).subscribeOn(Schedulers.io())
        .observeOn(AndroidSchedulers.mainThread())
        .subscribe {
            viewBinding.bLogin.isEnabled = it
        }
    subscriptions.add(emailObservable, passwordObservable, disposable)
}

override fun onResume() {
    super.onResume()
    validateForm()
}

override fun onPause() {
    subscriptions.clear()
    super.onPause()
}
person Abu Noman    schedule 28.08.2019
comment
ты тестировал? - person r4jiv007; 06.10.2019