[Android] Implement the new scheduler in the playlist adapter

Nicolas Pomepuy git at videolan.org
Tue Jul 25 14:57:29 UTC 2023


vlc-android | branch: master | Nicolas Pomepuy <nicolas at videolabs.io> | Thu Jul 20 11:24:44 2023 +0200| [238044419149d7552bd50c99feaa39386c143f93] | committer: Duncan McNamara

Implement the new scheduler in the playlist adapter

> https://code.videolan.org/videolan/vlc-android/commit/238044419149d7552bd50c99feaa39386c143f93
---

 .../src/org/videolan/vlc/gui/audio/AudioPlayer.kt  |  2 +
 .../org/videolan/vlc/gui/audio/PlaylistAdapter.kt  | 67 +++++++++++-----------
 .../videolan/vlc/gui/video/VideoPlayerActivity.kt  |  2 +
 3 files changed, 38 insertions(+), 33 deletions(-)

diff --git a/application/vlc-android/src/org/videolan/vlc/gui/audio/AudioPlayer.kt b/application/vlc-android/src/org/videolan/vlc/gui/audio/AudioPlayer.kt
index 5b2bb24c82..b2fa455fae 100644
--- a/application/vlc-android/src/org/videolan/vlc/gui/audio/AudioPlayer.kt
+++ b/application/vlc-android/src/org/videolan/vlc/gui/audio/AudioPlayer.kt
@@ -348,6 +348,8 @@ class AudioPlayer : Fragment(), PlaylistAdapter.IPlayer, TextWatcher, IAudioPlay
         showContext(activity, ctxReceiver, position, item, flags)
     }
 
+    override fun getLifeCycle() = this.lifecycle
+
     private suspend fun doUpdate() {
         if (isVisible && playlistModel.switchToVideo()) return
         updatePlayPause()
diff --git a/application/vlc-android/src/org/videolan/vlc/gui/audio/PlaylistAdapter.kt b/application/vlc-android/src/org/videolan/vlc/gui/audio/PlaylistAdapter.kt
index a81b9fdd1c..75eb82f16c 100644
--- a/application/vlc-android/src/org/videolan/vlc/gui/audio/PlaylistAdapter.kt
+++ b/application/vlc-android/src/org/videolan/vlc/gui/audio/PlaylistAdapter.kt
@@ -28,9 +28,9 @@ import android.content.Context
 import android.graphics.Typeface
 import android.graphics.drawable.BitmapDrawable
 import android.os.Build
+import android.os.Bundle
 import android.os.Handler
 import android.os.Looper
-import android.os.Message
 import android.view.LayoutInflater
 import android.view.View
 import android.view.ViewGroup
@@ -38,14 +38,15 @@ import android.widget.ImageView
 import android.widget.Toast
 import androidx.annotation.MainThread
 import androidx.constraintlayout.widget.ConstraintLayout
+import androidx.core.os.bundleOf
 import androidx.databinding.DataBindingUtil
 import androidx.fragment.app.Fragment
+import androidx.lifecycle.Lifecycle
 import androidx.recyclerview.widget.RecyclerView
 import org.videolan.libvlc.util.AndroidUtil
 import org.videolan.medialibrary.interfaces.media.MediaWrapper
 import org.videolan.resources.AppContextProvider
 import org.videolan.tools.Settings
-import org.videolan.tools.WeakHandler
 import org.videolan.tools.setGone
 import org.videolan.tools.setVisible
 import org.videolan.vlc.R
@@ -59,20 +60,22 @@ import org.videolan.vlc.gui.helpers.getBitmapFromDrawable
 import org.videolan.vlc.gui.view.MiniVisualizer
 import org.videolan.vlc.interfaces.SwipeDragHelperAdapter
 import org.videolan.vlc.media.MediaUtils
+import org.videolan.vlc.util.LifecycleAwareScheduler
 import org.videolan.vlc.util.MediaItemDiffCallback
+import org.videolan.vlc.util.SchedulerCallback
 import org.videolan.vlc.viewmodels.PlaylistModel
 import java.util.*
 
-private const val ACTION_MOVE = 0
-private const val ACTION_MOVED = 1
+private const val ACTION_MOVE = "action_move"
+private const val ACTION_MOVED = "action_moved"
 
-class PlaylistAdapter(private val player: IPlayer) : DiffUtilAdapter<MediaWrapper, PlaylistAdapter.ViewHolder>(), SwipeDragHelperAdapter {
+class PlaylistAdapter(private val player: IPlayer) : DiffUtilAdapter<MediaWrapper, PlaylistAdapter.ViewHolder>(), SwipeDragHelperAdapter, SchedulerCallback {
 
     private var defaultCoverVideo: BitmapDrawable
     private var defaultCoverAudio: BitmapDrawable
     private var model: PlaylistModel? = null
     private var currentPlayingVisu: MiniVisualizer? = null
-    private val handler by lazy(LazyThreadSafetyMode.NONE) { Handler(Looper.getMainLooper()) }
+    lateinit var scheduler: LifecycleAwareScheduler
 
     init {
         val ctx = when (player) {
@@ -83,6 +86,7 @@ class PlaylistAdapter(private val player: IPlayer) : DiffUtilAdapter<MediaWrappe
 
         defaultCoverAudio = BitmapDrawable(ctx.resources, getBitmapFromDrawable(ctx, R.drawable.ic_no_song_background))
         defaultCoverVideo = UiTools.getDefaultVideoDrawable(ctx)
+        scheduler =  LifecycleAwareScheduler(this)
     }
 
     var currentIndex = 0
@@ -97,12 +101,11 @@ class PlaylistAdapter(private val player: IPlayer) : DiffUtilAdapter<MediaWrappe
             }
         }
 
-    private val mHandler = PlaylistHandler(this)
-
     interface IPlayer {
         fun onPopupMenu(view: View, position: Int, item: MediaWrapper?)
         fun onSelectionSet(position: Int)
         fun playItem(position: Int, item: MediaWrapper)
+        fun getLifeCycle(): Lifecycle
     }
 
     override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
@@ -153,7 +156,7 @@ class PlaylistAdapter(private val player: IPlayer) : DiffUtilAdapter<MediaWrappe
 
     override fun onAttachedToRecyclerView(recyclerView: RecyclerView) {
         super.onAttachedToRecyclerView(recyclerView)
-        if (Settings.listTitleEllipsize == 4) enableMarqueeEffect(recyclerView, handler)
+        if (Settings.listTitleEllipsize == 4) enableMarqueeEffect(recyclerView, Handler(Looper.getMainLooper()))
     }
 
     override fun getItemCount() = dataset.size
@@ -173,7 +176,7 @@ class PlaylistAdapter(private val player: IPlayer) : DiffUtilAdapter<MediaWrappe
     override fun onItemMove(fromPosition: Int, toPosition: Int) {
         Collections.swap(dataset, fromPosition, toPosition)
         notifyItemMoved(fromPosition, toPosition)
-        mHandler.obtainMessage(ACTION_MOVE, fromPosition, toPosition).sendToTarget()
+        scheduler.startAction(ACTION_MOVE, bundleOf("from" to fromPosition, "to" to toPosition))
     }
 
     override fun onItemMoved(dragFrom: Int, dragTo: Int) {
@@ -232,33 +235,31 @@ class PlaylistAdapter(private val player: IPlayer) : DiffUtilAdapter<MediaWrappe
         }
     }
 
-    private class PlaylistHandler(owner: PlaylistAdapter) : WeakHandler<PlaylistAdapter>(owner) {
+    override fun createCB(): DiffCallback<MediaWrapper> = MediaItemDiffCallback()
 
-        var from = -1
-        var to = -1
+    fun setCurrentlyPlaying(playing: Boolean) {
+        if (playing) currentPlayingVisu?.start() else currentPlayingVisu?.stop()
+    }
 
-        override fun handleMessage(msg: Message) {
-            when (msg.what) {
-                ACTION_MOVE -> {
-                    removeMessages(ACTION_MOVED)
-                    if (from == -1) from = msg.arg1
-                    to = msg.arg2
-                    sendEmptyMessageDelayed(ACTION_MOVED, 1000)
-                }
-                ACTION_MOVED -> {
-                    val model = owner?.model ?: return
-                    if (to > from) ++to
-                    model.move(from, to)
-                    to = -1
-                    from = to
-                }
+    var from = -1
+    var to = -1
+    override fun onTaskTriggered(id: String, data: Bundle) {
+        when (id) {
+            ACTION_MOVE -> {
+                scheduler.cancelAction(ACTION_MOVED)
+                if (from == -1) from = data.getInt("from")
+                to = data.getInt("to")
+                scheduler.scheduleAction(ACTION_MOVED, 1000)
+            }
+            ACTION_MOVED -> {
+                val model = model ?: return
+                if (to > from) ++to
+                model.move(from, to)
+                to = -1
+                from = to
             }
         }
     }
 
-    override fun createCB(): DiffCallback<MediaWrapper> = MediaItemDiffCallback()
-
-    fun setCurrentlyPlaying(playing: Boolean) {
-        if (playing) currentPlayingVisu?.start() else currentPlayingVisu?.stop()
-    }
+    override fun getLifecycle() = player.getLifeCycle()
 }
diff --git a/application/vlc-android/src/org/videolan/vlc/gui/video/VideoPlayerActivity.kt b/application/vlc-android/src/org/videolan/vlc/gui/video/VideoPlayerActivity.kt
index a8b65ebe31..5ba39eca6f 100644
--- a/application/vlc-android/src/org/videolan/vlc/gui/video/VideoPlayerActivity.kt
+++ b/application/vlc-android/src/org/videolan/vlc/gui/video/VideoPlayerActivity.kt
@@ -1735,6 +1735,8 @@ open class VideoPlayerActivity : AppCompatActivity(), PlaybackService.Callback,
         popupMenu.show()
     }
 
+    override fun getLifeCycle() = this.lifecycle
+
     override fun onSelectionSet(position: Int) = overlayDelegate.playlist.scrollToPosition(position)
 
     override fun playItem(position: Int, item: MediaWrapper) {



More information about the Android mailing list