[Android] Thread playlist updates

Geoffrey Métais git at videolan.org
Tue Feb 21 14:44:31 CET 2017


vlc-android | branch: master | Geoffrey Métais <geoffrey.metais at gmail.com> | Tue Feb 21 14:32:29 2017 +0100| [c86a9db7dca52b885a446f44bda0748b301f777b] | committer: Geoffrey Métais

Thread playlist updates

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

 .../org/videolan/vlc/gui/audio/AudioPlayer.java    |  2 +-
 .../videolan/vlc/gui/audio/PlaylistAdapter.java    | 53 ++++++++++++++++++----
 .../helpers/SwipeDragItemTouchHelperCallback.java  |  4 +-
 .../vlc/gui/video/VideoPlayerActivity.java         |  2 +-
 .../vlc/interfaces/SwipeDragHelperAdapter.java     |  2 +
 5 files changed, 50 insertions(+), 13 deletions(-)

diff --git a/vlc-android/src/org/videolan/vlc/gui/audio/AudioPlayer.java b/vlc-android/src/org/videolan/vlc/gui/audio/AudioPlayer.java
index a366636..3579029 100644
--- a/vlc-android/src/org/videolan/vlc/gui/audio/AudioPlayer.java
+++ b/vlc-android/src/org/videolan/vlc/gui/audio/AudioPlayer.java
@@ -311,7 +311,7 @@ public class AudioPlayer extends PlaybackServiceFragment implements PlaybackServ
     public void updateList() {
         hideSearchField();
         if (mService != null)
-            mPlaylistAdapter.dispatchUpdate(mService.getMedias());
+            mPlaylistAdapter.update(mService.getMedias());
     }
 
     @Override
diff --git a/vlc-android/src/org/videolan/vlc/gui/audio/PlaylistAdapter.java b/vlc-android/src/org/videolan/vlc/gui/audio/PlaylistAdapter.java
index 8cebbfa..fee6872 100644
--- a/vlc-android/src/org/videolan/vlc/gui/audio/PlaylistAdapter.java
+++ b/vlc-android/src/org/videolan/vlc/gui/audio/PlaylistAdapter.java
@@ -37,7 +37,6 @@ import android.widget.Filter;
 import android.widget.Filterable;
 import android.widget.Toast;
 
-import org.videolan.libvlc.util.AndroidUtil;
 import org.videolan.medialibrary.media.MediaWrapper;
 import org.videolan.vlc.PlaybackService;
 import org.videolan.vlc.R;
@@ -49,14 +48,21 @@ import org.videolan.vlc.media.MediaUtils;
 import org.videolan.vlc.util.MediaItemDiffCallback;
 import org.videolan.vlc.util.WeakHandler;
 
+import java.util.ArrayDeque;
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.List;
+import java.util.concurrent.LinkedBlockingQueue;
+import java.util.concurrent.ThreadPoolExecutor;
+import java.util.concurrent.TimeUnit;
 
 public class PlaylistAdapter extends RecyclerView.Adapter<PlaylistAdapter.ViewHolder> implements SwipeDragHelperAdapter, Filterable {
 
     private static final String TAG = "VLC/PlaylistAdapter";
 
+    private ThreadPoolExecutor mThreadPool = new ThreadPoolExecutor(1, 1, 2, TimeUnit.SECONDS,
+            new LinkedBlockingQueue<Runnable>(), VLCApplication.THREAD_FACTORY);
+
     private ItemFilter mFilter = new ItemFilter();
     private PlaybackService mService = null;
     private IPlayer mAudioPlayer;
@@ -122,14 +128,41 @@ public class PlaylistAdapter extends RecyclerView.Adapter<PlaylistAdapter.ViewHo
         mDataSet.addAll(playList);
     }
 
+    private ArrayDeque<ArrayList<MediaWrapper>> mPendingUpdates = new ArrayDeque<>();
+
+    public boolean hasPendingUpdates() {
+        return !mPendingUpdates.isEmpty();
+    }
+
+    @MainThread
+    public void update(final ArrayList<MediaWrapper> newList) {
+        mPendingUpdates.add(newList);
+        if (mPendingUpdates.size() == 1)
+            internalUpdate(newList);
+    }
+
     @MainThread
-    public void dispatchUpdate(final List<MediaWrapper> newList) {
-        final DiffUtil.DiffResult result = DiffUtil.calculateDiff(new MediaItemDiffCallback(mDataSet, newList), false);
-        mDataSet.clear();
-        addAll(newList);
-        result.dispatchUpdatesTo(this);
-        if (mService != null)
-            setCurrentIndex(mService.getCurrentMediaPosition());
+    private void internalUpdate(final List<MediaWrapper> newList) {
+        mThreadPool.execute(new Runnable() {
+            @Override
+            public void run() {
+                final DiffUtil.DiffResult result = DiffUtil.calculateDiff(new MediaItemDiffCallback(mDataSet, newList), false);
+                VLCApplication.runOnMainThread(new Runnable() {
+                    @Override
+                    public void run() {
+                        mPendingUpdates.remove();
+                        mDataSet.clear();
+                        addAll(newList);
+                        result.dispatchUpdatesTo(PlaylistAdapter.this);
+                        if (mService != null)
+                            setCurrentIndex(mService.getCurrentMediaPosition());
+                        if (!mPendingUpdates.isEmpty())
+                            internalUpdate(mPendingUpdates.peek());
+                    }
+                });
+            }
+        });
+
     }
 
     @MainThread
@@ -220,7 +253,7 @@ public class PlaylistAdapter extends RecyclerView.Adapter<PlaylistAdapter.ViewHo
     @MainThread
     public void restoreList() {
         if (mOriginalDataSet != null) {
-            dispatchUpdate(new ArrayList<>(mOriginalDataSet));
+            update(new ArrayList<>(mOriginalDataSet));
             mOriginalDataSet = null;
         }
     }
@@ -302,7 +335,7 @@ public class PlaylistAdapter extends RecyclerView.Adapter<PlaylistAdapter.ViewHo
 
         @Override
         protected void publishResults(CharSequence charSequence, FilterResults filterResults) {
-            dispatchUpdate((ArrayList<MediaWrapper>) filterResults.values);
+            update((ArrayList<MediaWrapper>) filterResults.values);
         }
     }
 }
diff --git a/vlc-android/src/org/videolan/vlc/gui/helpers/SwipeDragItemTouchHelperCallback.java b/vlc-android/src/org/videolan/vlc/gui/helpers/SwipeDragItemTouchHelperCallback.java
index c9b29ac..fb295e2 100644
--- a/vlc-android/src/org/videolan/vlc/gui/helpers/SwipeDragItemTouchHelperCallback.java
+++ b/vlc-android/src/org/videolan/vlc/gui/helpers/SwipeDragItemTouchHelperCallback.java
@@ -2,7 +2,7 @@
  * *************************************************************************
  *  SwipeDragItemTouchHelperCallback.java
  * **************************************************************************
- *  Copyright © 2015 VLC authors and VideoLAN
+ *  Copyright © 2015-2017 VLC authors and VideoLAN
  *  Author: Geoffrey Métais
  *
  *  This program is free software; you can redistribute it and/or modify
@@ -38,6 +38,8 @@ public class SwipeDragItemTouchHelperCallback extends ItemTouchHelper.Callback {
 
     @Override
     public int getMovementFlags(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) {
+        if (mAdapter.hasPendingUpdates())
+            return 0;
         int dragFlags = ItemTouchHelper.UP | ItemTouchHelper.DOWN;
         int swipeFlags = ItemTouchHelper.START | ItemTouchHelper.END;
         return makeMovementFlags(dragFlags, swipeFlags);
diff --git a/vlc-android/src/org/videolan/vlc/gui/video/VideoPlayerActivity.java b/vlc-android/src/org/videolan/vlc/gui/video/VideoPlayerActivity.java
index 1a1753b..19067bb 100644
--- a/vlc-android/src/org/videolan/vlc/gui/video/VideoPlayerActivity.java
+++ b/vlc-android/src/org/videolan/vlc/gui/video/VideoPlayerActivity.java
@@ -2339,7 +2339,7 @@ public class VideoPlayerActivity extends AppCompatActivity implements IVLCVout.C
         if (mService == null || mPlaylistAdapter == null)
             return;
 
-        mPlaylistAdapter.dispatchUpdate(mService.getMedias());
+        mPlaylistAdapter.update(mService.getMedias());
     }
 
     @Override
diff --git a/vlc-android/src/org/videolan/vlc/interfaces/SwipeDragHelperAdapter.java b/vlc-android/src/org/videolan/vlc/interfaces/SwipeDragHelperAdapter.java
index 845bf5d..098e87f 100644
--- a/vlc-android/src/org/videolan/vlc/interfaces/SwipeDragHelperAdapter.java
+++ b/vlc-android/src/org/videolan/vlc/interfaces/SwipeDragHelperAdapter.java
@@ -28,4 +28,6 @@ public interface SwipeDragHelperAdapter {
     void onItemMove(int fromPosition, int toPosition);
 
     void onItemDismiss(int position);
+
+    boolean hasPendingUpdates();
 }



More information about the Android mailing list