mirror of
https://github.com/kiwix/kiwix-android.git
synced 2025-09-17 19:35:36 -04:00
Introduced a mutex to manage concurrency in the search functionality. This enables proper clearing of the first running job before executing a new one. By implementing this approach, we ensure that access to the libzim search results occurs one at a time, resolving the crashing issue caused by multiple attempts to access libzim resources.
* Replaced the `cancel` function for the Job with `cancelAndJoin`, ensuring that it thoroughly cancels the first job before initiating the new task.
This commit is contained in:
parent
6d5e50d0ef
commit
a07bb680c3
@ -43,7 +43,10 @@ import androidx.recyclerview.widget.RecyclerView
|
||||
import io.reactivex.android.schedulers.AndroidSchedulers
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.Job
|
||||
import kotlinx.coroutines.cancelAndJoin
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.sync.Mutex
|
||||
import kotlinx.coroutines.sync.withLock
|
||||
import kotlinx.coroutines.withContext
|
||||
import org.kiwix.kiwixmobile.core.R
|
||||
import org.kiwix.kiwixmobile.core.base.BaseActivity
|
||||
@ -86,6 +89,7 @@ class SearchFragment : BaseFragment() {
|
||||
private var searchAdapter: SearchAdapter? = null
|
||||
private var isDataLoading = false
|
||||
private var renderingJob: Job? = null
|
||||
private val searchMutex = Mutex()
|
||||
|
||||
override fun inject(baseActivity: BaseActivity) {
|
||||
baseActivity.cachedComponent.inject(this)
|
||||
@ -252,22 +256,25 @@ class SearchFragment : BaseFragment() {
|
||||
)
|
||||
}
|
||||
|
||||
private fun render(state: SearchState) {
|
||||
renderingJob?.cancel()
|
||||
isDataLoading = false
|
||||
searchInTextMenuItem?.isVisible = state.searchOrigin == FromWebView
|
||||
searchInTextMenuItem?.isEnabled = state.searchTerm.isNotBlank()
|
||||
fragmentSearchBinding?.searchLoadingIndicator?.isShowing(true)
|
||||
renderingJob = searchViewModel.viewModelScope.launch(Dispatchers.Main) {
|
||||
val searchResult = withContext(Dispatchers.IO) {
|
||||
state.getVisibleResults(0, renderingJob)
|
||||
}
|
||||
private suspend fun render(state: SearchState) {
|
||||
searchMutex.withLock {
|
||||
// `cancelAndJoin` cancels the previous running job and waits for it to completely cancel.
|
||||
renderingJob?.cancelAndJoin()
|
||||
isDataLoading = false
|
||||
searchInTextMenuItem?.isVisible = state.searchOrigin == FromWebView
|
||||
searchInTextMenuItem?.isEnabled = state.searchTerm.isNotBlank()
|
||||
fragmentSearchBinding?.searchLoadingIndicator?.isShowing(true)
|
||||
renderingJob = searchViewModel.viewModelScope.launch(Dispatchers.Main) {
|
||||
val searchResult = withContext(Dispatchers.IO) {
|
||||
state.getVisibleResults(0, renderingJob)
|
||||
}
|
||||
|
||||
fragmentSearchBinding?.searchLoadingIndicator?.isShowing(false)
|
||||
fragmentSearchBinding?.searchLoadingIndicator?.isShowing(false)
|
||||
|
||||
searchResult?.let {
|
||||
fragmentSearchBinding?.searchNoResults?.isVisible = it.isEmpty()
|
||||
searchAdapter?.items = it
|
||||
searchResult?.let {
|
||||
fragmentSearchBinding?.searchNoResults?.isVisible = it.isEmpty()
|
||||
searchAdapter?.items = it
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user