mirror of
https://github.com/mihonapp/mihon.git
synced 2024-11-07 11:17:25 +01:00
Address coroutine scope leaks in custom views
This commit is contained in:
parent
b18a794eca
commit
8e613d03e3
@ -10,15 +10,10 @@ import eu.davidea.flexibleadapter.items.IFlexible
|
|||||||
import eu.davidea.viewholders.FlexibleViewHolder
|
import eu.davidea.viewholders.FlexibleViewHolder
|
||||||
import eu.kanade.tachiyomi.R
|
import eu.kanade.tachiyomi.R
|
||||||
import eu.kanade.tachiyomi.source.model.Filter
|
import eu.kanade.tachiyomi.source.model.Filter
|
||||||
import kotlinx.coroutines.MainScope
|
import eu.kanade.tachiyomi.widget.SimpleTextWatcher
|
||||||
import kotlinx.coroutines.flow.launchIn
|
|
||||||
import kotlinx.coroutines.flow.onEach
|
|
||||||
import reactivecircus.flowbinding.android.widget.textChanges
|
|
||||||
|
|
||||||
open class TextItem(val filter: Filter.Text) : AbstractFlexibleItem<TextItem.Holder>() {
|
open class TextItem(val filter: Filter.Text) : AbstractFlexibleItem<TextItem.Holder>() {
|
||||||
|
|
||||||
private val scope = MainScope()
|
|
||||||
|
|
||||||
override fun getLayoutRes(): Int {
|
override fun getLayoutRes(): Int {
|
||||||
return R.layout.navigation_view_text
|
return R.layout.navigation_view_text
|
||||||
}
|
}
|
||||||
@ -30,9 +25,11 @@ open class TextItem(val filter: Filter.Text) : AbstractFlexibleItem<TextItem.Hol
|
|||||||
override fun bindViewHolder(adapter: FlexibleAdapter<IFlexible<RecyclerView.ViewHolder>>, holder: Holder, position: Int, payloads: List<Any?>?) {
|
override fun bindViewHolder(adapter: FlexibleAdapter<IFlexible<RecyclerView.ViewHolder>>, holder: Holder, position: Int, payloads: List<Any?>?) {
|
||||||
holder.wrapper.hint = filter.name
|
holder.wrapper.hint = filter.name
|
||||||
holder.edit.setText(filter.state)
|
holder.edit.setText(filter.state)
|
||||||
holder.edit.textChanges()
|
holder.edit.addTextChangedListener(object : SimpleTextWatcher() {
|
||||||
.onEach { filter.state = it.toString() }
|
override fun onTextChanged(text: CharSequence, start: Int, before: Int, count: Int) {
|
||||||
.launchIn(scope)
|
filter.state = text.toString()
|
||||||
|
}
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun equals(other: Any?): Boolean {
|
override fun equals(other: Any?): Boolean {
|
||||||
|
@ -97,7 +97,7 @@ class LibraryAdapter(private val controller: LibraryController) : RecyclerViewPa
|
|||||||
fun onDestroy() {
|
fun onDestroy() {
|
||||||
for (view in boundViews) {
|
for (view in boundViews) {
|
||||||
if (view is LibraryCategoryView) {
|
if (view is LibraryCategoryView) {
|
||||||
view.unsubscribe()
|
view.onDestroy()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -20,6 +20,7 @@ import eu.kanade.tachiyomi.util.system.toast
|
|||||||
import eu.kanade.tachiyomi.util.view.inflate
|
import eu.kanade.tachiyomi.util.view.inflate
|
||||||
import eu.kanade.tachiyomi.widget.AutofitRecyclerView
|
import eu.kanade.tachiyomi.widget.AutofitRecyclerView
|
||||||
import kotlinx.coroutines.MainScope
|
import kotlinx.coroutines.MainScope
|
||||||
|
import kotlinx.coroutines.cancel
|
||||||
import kotlinx.coroutines.flow.launchIn
|
import kotlinx.coroutines.flow.launchIn
|
||||||
import kotlinx.coroutines.flow.onEach
|
import kotlinx.coroutines.flow.onEach
|
||||||
import reactivecircus.flowbinding.recyclerview.scrollStateChanges
|
import reactivecircus.flowbinding.recyclerview.scrollStateChanges
|
||||||
@ -155,7 +156,12 @@ class LibraryCategoryView @JvmOverloads constructor(context: Context, attrs: Att
|
|||||||
unsubscribe()
|
unsubscribe()
|
||||||
}
|
}
|
||||||
|
|
||||||
fun unsubscribe() {
|
fun onDestroy() {
|
||||||
|
unsubscribe()
|
||||||
|
scope.cancel()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun unsubscribe() {
|
||||||
subscriptions.clear()
|
subscriptions.clear()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -7,10 +7,6 @@ import android.view.LayoutInflater
|
|||||||
import android.view.View
|
import android.view.View
|
||||||
import android.widget.LinearLayout
|
import android.widget.LinearLayout
|
||||||
import eu.kanade.tachiyomi.databinding.DownloadCustomAmountBinding
|
import eu.kanade.tachiyomi.databinding.DownloadCustomAmountBinding
|
||||||
import kotlinx.coroutines.MainScope
|
|
||||||
import kotlinx.coroutines.flow.launchIn
|
|
||||||
import kotlinx.coroutines.flow.onEach
|
|
||||||
import reactivecircus.flowbinding.android.widget.textChanges
|
|
||||||
import timber.log.Timber
|
import timber.log.Timber
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -35,8 +31,6 @@ class DialogCustomDownloadView @JvmOverloads constructor(context: Context, attrs
|
|||||||
*/
|
*/
|
||||||
private var max = 0
|
private var max = 0
|
||||||
|
|
||||||
private val scope = MainScope()
|
|
||||||
|
|
||||||
private val binding: DownloadCustomAmountBinding
|
private val binding: DownloadCustomAmountBinding
|
||||||
|
|
||||||
init {
|
init {
|
||||||
@ -71,16 +65,16 @@ class DialogCustomDownloadView @JvmOverloads constructor(context: Context, attrs
|
|||||||
}
|
}
|
||||||
|
|
||||||
// When user inputs custom number set amount equal to input.
|
// When user inputs custom number set amount equal to input.
|
||||||
binding.myNumber.textChanges()
|
binding.myNumber.addTextChangedListener(object : SimpleTextWatcher() {
|
||||||
.onEach {
|
override fun onTextChanged(text: CharSequence, start: Int, before: Int, count: Int) {
|
||||||
try {
|
try {
|
||||||
amount = getAmount(Integer.parseInt(it.toString()))
|
amount = getAmount(text.toString().toInt())
|
||||||
} catch (error: NumberFormatException) {
|
} catch (error: NumberFormatException) {
|
||||||
// Catch NumberFormatException to prevent parse exception when input is empty.
|
// Catch NumberFormatException to prevent parse exception when input is empty.
|
||||||
Timber.e(error)
|
Timber.e(error)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.launchIn(scope)
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -0,0 +1,15 @@
|
|||||||
|
package eu.kanade.tachiyomi.widget
|
||||||
|
|
||||||
|
import android.text.Editable
|
||||||
|
import android.text.TextWatcher
|
||||||
|
|
||||||
|
open class SimpleTextWatcher : TextWatcher {
|
||||||
|
override fun beforeTextChanged(text: CharSequence, start: Int, count: Int, after: Int) {
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onTextChanged(text: CharSequence, start: Int, before: Int, count: Int) {
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun afterTextChanged(text: Editable) {
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user