[Android] Update headers sooner from worker thread

Geoffrey Métais git at videolan.org
Thu Feb 14 11:59:28 CET 2019


vlc-android | branch: master | Geoffrey Métais <geoffrey.metais at gmail.com> | Thu Feb 14 11:57:25 2019 +0100| [6dd8dcaa33ea704772d4940d57313358f5cb5e88] | committer: Geoffrey Métais

Update headers sooner from worker thread

> https://code.videolan.org/videolan/vlc-android/commit/6dd8dcaa33ea704772d4940d57313358f5cb5e88
---

 .../src/org/videolan/vlc/gui/view/FastScroller.kt     |  9 ++++++---
 .../org/videolan/vlc/viewmodels/paged/MLPagedModel.kt | 19 +++++++++++++------
 .../videolan/vlc/viewmodels/paged/PagedAlbumsModel.kt |  2 +-
 .../vlc/viewmodels/paged/PagedArtistsModel.kt         |  2 +-
 4 files changed, 21 insertions(+), 11 deletions(-)

diff --git a/vlc-android/src/org/videolan/vlc/gui/view/FastScroller.kt b/vlc-android/src/org/videolan/vlc/gui/view/FastScroller.kt
index 1575736f8..534f3b4cd 100644
--- a/vlc-android/src/org/videolan/vlc/gui/view/FastScroller.kt
+++ b/vlc-android/src/org/videolan/vlc/gui/view/FastScroller.kt
@@ -43,6 +43,7 @@ import androidx.recyclerview.widget.LinearLayoutManager
 import androidx.recyclerview.widget.RecyclerView
 import com.google.android.material.appbar.AppBarLayout
 import com.google.android.material.floatingactionbutton.FloatingActionButton
+import kotlinx.coroutines.*
 import org.videolan.medialibrary.media.MediaLibraryItem
 import org.videolan.vlc.R
 import org.videolan.vlc.util.WeakHandler
@@ -60,7 +61,9 @@ private const val SHOW_SCROLLER = 2
 
 private const val ITEM_THRESHOLD = 25
 
-class FastScroller : LinearLayout {
+ at ExperimentalCoroutinesApi
+class FastScroller : LinearLayout, CoroutineScope {
+    override val coroutineContext = Dispatchers.Main.immediate + SupervisorJob()
     private var currentHeight: Int = 0
     private var itemCount: Int = 0
     private var recyclerviewTotalHeight: Int = 0
@@ -340,7 +343,7 @@ class FastScroller : LinearLayout {
     /**
      * Updates the position of the bubble and refresh the letter
      */
-    private fun updatePositions() {
+    private fun updatePositions() = launch {
         val sb = StringBuilder()
         val verticalScrollOffset = recyclerView.computeVerticalScrollOffset()
         recyclerviewTotalHeight = recyclerView.computeVerticalScrollRange() - recyclerView.computeVerticalScrollExtent()
@@ -359,7 +362,7 @@ class FastScroller : LinearLayout {
             if (!sectionforPosition.isEmpty()) {
                 bubble.text = sb.toString()
             }
-            return
+            return at launch
         }
         if (this at FastScroller.visibility == View.INVISIBLE)
             handler.sendEmptyMessage(SHOW_SCROLLER)
diff --git a/vlc-android/src/org/videolan/vlc/viewmodels/paged/MLPagedModel.kt b/vlc-android/src/org/videolan/vlc/viewmodels/paged/MLPagedModel.kt
index ce9dcf172..c4af1e8d8 100644
--- a/vlc-android/src/org/videolan/vlc/viewmodels/paged/MLPagedModel.kt
+++ b/vlc-android/src/org/videolan/vlc/viewmodels/paged/MLPagedModel.kt
@@ -8,6 +8,8 @@ import androidx.paging.LivePagedListBuilder
 import androidx.paging.PagedList
 import androidx.paging.PositionalDataSource
 import kotlinx.coroutines.*
+import kotlinx.coroutines.sync.Mutex
+import kotlinx.coroutines.sync.withLock
 import org.videolan.medialibrary.Medialibrary
 import org.videolan.medialibrary.media.MediaLibraryItem
 import org.videolan.vlc.util.MEDIALIBRARY_PAGE_SIZE
@@ -16,11 +18,13 @@ import org.videolan.vlc.util.Settings
 import org.videolan.vlc.util.retry
 import org.videolan.vlc.viewmodels.SortableModel
 
+ at ExperimentalCoroutinesApi
 abstract class MLPagedModel<T : MediaLibraryItem>(context: Context) : SortableModel(context), Medialibrary.OnMedialibraryReadyListener, Medialibrary.OnDeviceChangeListener {
     protected val medialibrary = Medialibrary.getInstance()
     val loading = MutableLiveData<Boolean>().apply { value = false }
 
     protected val headers = SparseArrayCompat<String>()
+    private val mutex = Mutex()
 
     private val pagingConfig = PagedList.Config.Builder()
             .setPageSize(MEDIALIBRARY_PAGE_SIZE)
@@ -63,7 +67,7 @@ abstract class MLPagedModel<T : MediaLibraryItem>(context: Context) : SortableMo
     abstract fun getAll() : Array<T>
 
     override fun sort(sort: Int) {
-        headers.clear()
+        launch(Dispatchers.Unconfined) { mutex.withLock { headers.clear() } }
         if (this.sort != sort) {
             this.sort = sort
             desc = false
@@ -94,7 +98,7 @@ abstract class MLPagedModel<T : MediaLibraryItem>(context: Context) : SortableMo
     }
 
     override fun refresh(): Boolean {
-        launch { headers.clear() }
+        launch(Dispatchers.Unconfined) { mutex.withLock { headers.clear() } }
         if (this::restoreJob.isInitialized && restoreJob.isActive) restoreJob.cancel()
         if (pagedList.value?.dataSource?.isInvalid == false) {
             loading.postValue(true)
@@ -103,7 +107,7 @@ abstract class MLPagedModel<T : MediaLibraryItem>(context: Context) : SortableMo
         return true
     }
 
-    protected fun completeHeaders(list: Array<out MediaLibraryItem>, startposition: Int) {
+    protected fun completeHeaders(list: Array<T>, startposition: Int) {
         for ((position, item) in list.withIndex()) {
             val previous = when {
                 position > 0 -> list[position-1]
@@ -111,13 +115,16 @@ abstract class MLPagedModel<T : MediaLibraryItem>(context: Context) : SortableMo
                 else -> null
             }
             ModelsHelper.getHeader(context, sort, item, previous)?.let {
-                launch { headers.put(startposition+position, it) }
+                launch(Dispatchers.Unconfined) {
+                    mutex.withLock { headers.put(startposition+position, it) }
+
+                }
             }
         }
     }
 
-    fun getSectionforPosition(position: Int): String {
-        for (pos in 0 until headers.size()) if (position < headers.keyAt(pos)) return headers.valueAt(pos)
+    suspend fun getSectionforPosition(position: Int): String {
+        mutex.withLock { for (pos in 0 until headers.size()) if (position < headers.keyAt(pos)) return headers.valueAt(pos) }
         return ""
     }
 
diff --git a/vlc-android/src/org/videolan/vlc/viewmodels/paged/PagedAlbumsModel.kt b/vlc-android/src/org/videolan/vlc/viewmodels/paged/PagedAlbumsModel.kt
index 4a1abdea8..7bc727881 100644
--- a/vlc-android/src/org/videolan/vlc/viewmodels/paged/PagedAlbumsModel.kt
+++ b/vlc-android/src/org/videolan/vlc/viewmodels/paged/PagedAlbumsModel.kt
@@ -45,7 +45,7 @@ class PagedAlbumsModel(context: Context, val parent: MediaLibraryItem? = null) :
             is Genre -> parent.searchAlbums(filterQuery, sort, desc, loadSize, startposition)
             else -> medialibrary.searchAlbum(filterQuery, sort, desc, loadSize, startposition)
         }
-        list?.also { completeHeaders(it, 0) }
+        list?.let { completeHeaders(it, 0) }
         return list
     }
 
diff --git a/vlc-android/src/org/videolan/vlc/viewmodels/paged/PagedArtistsModel.kt b/vlc-android/src/org/videolan/vlc/viewmodels/paged/PagedArtistsModel.kt
index cf4641d37..719e48e33 100644
--- a/vlc-android/src/org/videolan/vlc/viewmodels/paged/PagedArtistsModel.kt
+++ b/vlc-android/src/org/videolan/vlc/viewmodels/paged/PagedArtistsModel.kt
@@ -26,7 +26,7 @@ class PagedArtistsModel(context: Context, private var showAll: Boolean = false):
     override fun getPage(loadSize: Int, startposition: Int): Array<Artist> {
         val list = if (filterQuery == null) medialibrary.getPagedArtists(showAll, sort, desc, loadSize, startposition)
         else medialibrary.searchArtist(filterQuery, sort, desc, loadSize, startposition)
-        list?.also { completeHeaders(it, 0) }
+        list?.let { completeHeaders(it, 0) }
         return list
     }
 



More information about the Android mailing list