[Android] [PATCH] Thread list updates in audio browser

Geoffrey Métais geoffrey.metais at gmail.com
Fri Nov 21 15:46:41 CET 2014


---
 .../vlc/gui/audio/AudioAlbumsSongsFragment.java    |  35 +++--
 .../vlc/gui/audio/AudioBrowserFragment.java        | 159 ++++++++++-----------
 .../vlc/gui/audio/AudioBrowserListAdapter.java     |  55 ++++++-
 3 files changed, 150 insertions(+), 99 deletions(-)

diff --git a/vlc-android/src/org/videolan/vlc/gui/audio/AudioAlbumsSongsFragment.java b/vlc-android/src/org/videolan/vlc/gui/audio/AudioAlbumsSongsFragment.java
index e4967b9..5197579 100644
--- a/vlc-android/src/org/videolan/vlc/gui/audio/AudioAlbumsSongsFragment.java
+++ b/vlc-android/src/org/videolan/vlc/gui/audio/AudioAlbumsSongsFragment.java
@@ -36,6 +36,7 @@ import org.videolan.vlc.util.VLCRunnable;
 import org.videolan.vlc.widget.FlingViewGroup;
 
 import android.annotation.TargetApi;
+import android.app.Activity;
 import android.app.AlertDialog;
 import android.content.Context;
 import android.os.Build;
@@ -312,21 +313,33 @@ public class AudioAlbumsSongsFragment extends Fragment {
     }
 
     private void updateList() {
-        if (mediaList == null)
+        if (mediaList == null || getActivity() == null)
             return;
 
+        final Activity activity = getActivity();
+
         mAlbumsAdapter.clear();
         mSongsAdapter.clear();
-
-        Collections.sort(mediaList, MediaComparators.byAlbum);
-
-        for (int i = 0; i < mediaList.size(); ++i) {
-            Media media = mediaList.get(i);
-            mAlbumsAdapter.addSeparator(media.getArtist(), media);
-            mAlbumsAdapter.add(media.getAlbum(), null, media);
-            mSongsAdapter.addSeparator(media.getAlbum(), media);
-            mSongsAdapter.add(media.getTitle(), null, media);
-        }
+        new Thread(new Runnable() {
+            @Override
+            public void run() {
+                Collections.sort(mediaList, MediaComparators.byAlbum);
+                activity.runOnUiThread(new Runnable() {
+                    @Override
+                    public void run() {
+                        for (int i = 0; i < mediaList.size(); ++i) {
+                            Media media = mediaList.get(i);
+                            mAlbumsAdapter.addSeparator(media.getArtist(), media);
+                            mAlbumsAdapter.add(media.getAlbum(), null, media);
+                            mSongsAdapter.addSeparator(media.getAlbum(), media);
+                            mSongsAdapter.add(media.getTitle(), null, media);
+                        }
+                        mAlbumsAdapter.notifyDataSetChanged();
+                        mSongsAdapter.notifyDataSetChanged();
+                    }
+                });
+            }
+        }).start();
     }
 
     OnItemClickListener albumsListener = new OnItemClickListener() {
diff --git a/vlc-android/src/org/videolan/vlc/gui/audio/AudioBrowserFragment.java b/vlc-android/src/org/videolan/vlc/gui/audio/AudioBrowserFragment.java
index d8d9b08..5105869 100644
--- a/vlc-android/src/org/videolan/vlc/gui/audio/AudioBrowserFragment.java
+++ b/vlc-android/src/org/videolan/vlc/gui/audio/AudioBrowserFragment.java
@@ -20,25 +20,8 @@
 
 package org.videolan.vlc.gui.audio;
 
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-
-import org.videolan.libvlc.LibVlcUtil;
-import org.videolan.libvlc.Media;
-import org.videolan.vlc.MediaLibrary;
-import org.videolan.vlc.R;
-import org.videolan.vlc.audio.AudioServiceController;
-import org.videolan.vlc.gui.CommonDialogs;
-import org.videolan.vlc.gui.MainActivity;
-import org.videolan.vlc.util.AndroidDevices;
-import org.videolan.vlc.util.VLCRunnable;
-import org.videolan.vlc.util.WeakHandler;
-import org.videolan.vlc.widget.FlingViewGroup;
-import org.videolan.vlc.widget.FlingViewGroup.ViewSwitchListener;
-import org.videolan.vlc.widget.HeaderScrollView;
-
 import android.annotation.TargetApi;
+import android.app.Activity;
 import android.app.AlertDialog;
 import android.os.Build;
 import android.os.Bundle;
@@ -48,6 +31,7 @@ import android.support.v4.app.Fragment;
 import android.support.v7.app.ActionBarActivity;
 import android.view.ContextMenu;
 import android.view.ContextMenu.ContextMenuInfo;
+import android.view.KeyEvent;
 import android.view.LayoutInflater;
 import android.view.Menu;
 import android.view.MenuInflater;
@@ -64,7 +48,24 @@ import android.widget.ExpandableListView.ExpandableListContextMenuInfo;
 import android.widget.ListView;
 import android.widget.PopupMenu;
 import android.widget.PopupMenu.OnMenuItemClickListener;
-import android.view.KeyEvent;
+
+import org.videolan.libvlc.LibVlcUtil;
+import org.videolan.libvlc.Media;
+import org.videolan.vlc.MediaLibrary;
+import org.videolan.vlc.R;
+import org.videolan.vlc.audio.AudioServiceController;
+import org.videolan.vlc.gui.CommonDialogs;
+import org.videolan.vlc.gui.MainActivity;
+import org.videolan.vlc.util.AndroidDevices;
+import org.videolan.vlc.util.VLCRunnable;
+import org.videolan.vlc.util.WeakHandler;
+import org.videolan.vlc.widget.FlingViewGroup;
+import org.videolan.vlc.widget.FlingViewGroup.ViewSwitchListener;
+import org.videolan.vlc.widget.HeaderScrollView;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
 
 public class AudioBrowserFragment extends Fragment {
     public final static String TAG = "VLC/AudioBrowserFragment";
@@ -173,15 +174,21 @@ public class AudioBrowserFragment extends Fragment {
         mFlingViewGroup.setPosition(mFlingViewPosition);
         mHeader.highlightTab(-1, mFlingViewPosition);
         mHeader.scroll(mFlingViewPosition / 3.f);
-        updateLists();
+        if (!mMediaLibrary.isWorking())
+            updateLists();
         mMediaLibrary.addUpdateHandler(mHandler);
     }
 
-    private void focusHelper(boolean idIsEmpty, int listId) {
-        View parent = getView();
-        MainActivity main = (MainActivity)getActivity();
-        main.setMenuFocusDown(false, R.id.header);
-        main.setSearchAsFocusDown(idIsEmpty, parent, listId);
+    private void focusHelper(final boolean idIsEmpty, final int listId) {
+        final View parent = getView();
+        final MainActivity main = (MainActivity)getActivity();
+        main.runOnUiThread(new Runnable() {
+            @Override
+            public void run() {
+                main.setMenuFocusDown(false, R.id.header);
+                main.setSearchAsFocusDown(idIsEmpty, parent, listId);
+            }
+        });
     }
 
     // Focus support. Start.
@@ -300,7 +307,7 @@ public class AudioBrowserFragment extends Fragment {
             menu.setGroupVisible(R.id.songs_view_only, false);
             menu.setGroupVisible(R.id.phone_only, false);
         }
-        if (pos == MODE_ARTIST || v.getId() == MODE_GENRE) {
+        if (pos == MODE_ARTIST || pos == MODE_GENRE) {
             MenuItem play = menu.findItem(R.id.audio_list_browser_play);
             play.setVisible(true);
         }
@@ -452,71 +459,53 @@ public class AudioBrowserFragment extends Fragment {
     };
 
     private void updateLists() {
-        List<Media> audioList = MediaLibrary.getInstance().getAudioItems();
-        int listId = MODE_TOTAL;
-		int i;
-
-        if (audioList.isEmpty()){
-            mEmptyView.setVisibility(View.VISIBLE);
-            listId = MODE_SONG;
-        } else
-            mEmptyView.setVisibility(View.GONE);
-
+        final Activity context = getActivity();
         mSongsAdapter.clear();
         mArtistsAdapter.clear();
         mAlbumsAdapter.clear();
         mGenresAdapter.clear();
+        final List<Media> audioList = MediaLibrary.getInstance().getAudioItems();
+        if (audioList.isEmpty()){
+            mEmptyView.setVisibility(View.VISIBLE);
+            focusHelper(true, R.id.artists_list);
+        } else {
+            mEmptyView.setVisibility(View.GONE);
 
-        Collections.sort(audioList, MediaComparators.byName);
-        for (i = 0; i < audioList.size(); i++) {
-            Media media = audioList.get(i);
-            mSongsAdapter.add(media.getTitle(), media.getArtist(), media);
-        }
-        mSongsAdapter.addScrollSections();
-        if ((listId == MODE_TOTAL) && (i > 0))
-            listId = MODE_SONG;
-
-        Collections.sort(audioList, MediaComparators.byArtist);
-        for (i = 0; i < audioList.size(); i++) {
-            Media media = audioList.get(i);
-            mArtistsAdapter.add(media.getArtist(), null, media);
-        }
-        mArtistsAdapter.addLetterSeparators();
-        if (i > 0)
-            listId = MODE_ARTIST;
-
-        Collections.sort(audioList, MediaComparators.byAlbum);
-        for (i = 0; i < audioList.size(); i++) {
-            Media media = audioList.get(i);
-            mAlbumsAdapter.add(media.getAlbum(), media.getArtist(), media);
-        }
-        mAlbumsAdapter.addLetterSeparators();
-        if ((listId == MODE_TOTAL) && (i > 0))
-            listId = MODE_ALBUM;
-
-        Collections.sort(audioList, MediaComparators.byGenre);
-        for (i = 0; i < audioList.size(); i++) {
-            Media media = audioList.get(i);
-            mGenresAdapter.add(media.getGenre(), null, media);
-        }
-        mGenresAdapter.addLetterSeparators();
-        if ((listId == MODE_TOTAL) && (i>0))
-            listId = MODE_GENRE;
-
-        mSongsAdapter.notifyDataSetChanged();
-        mArtistsAdapter.notifyDataSetChanged();
-        mAlbumsAdapter.notifyDataSetChanged();
-        mGenresAdapter.notifyDataSetChanged();
-        // Refresh the fast scroll data, since SectionIndexer doesn't respect notifyDataSetChanged
-        int[] lists = { R.id.artists_list, R.id.albums_list, R.id.songs_list, R.id.genres_list };
-        if(getView() != null) {
-            for(int r : lists) {
-                ListView l = (ListView)getView().findViewById(r);
-                l.setFastScrollEnabled(false);
-                l.setFastScrollEnabled(true);
-            }
+            new Thread(new Runnable() {
+                @Override
+                public void run() {
+
+                    Collections.sort(audioList, MediaComparators.byArtist);
+                    mArtistsAdapter.addAll(audioList, AudioBrowserListAdapter.TYPE_ARTISTS);
+
+                    Collections.sort(audioList, MediaComparators.byName);
+                    mSongsAdapter.addAll(audioList, AudioBrowserListAdapter.TYPE_SONGS);
+
+                    Collections.sort(audioList, MediaComparators.byAlbum);
+                    mAlbumsAdapter.addAll(audioList, AudioBrowserListAdapter.TYPE_ALBUMS);
+
+                    Collections.sort(audioList, MediaComparators.byGenre);
+                    mGenresAdapter.addAll(audioList, AudioBrowserListAdapter.TYPE_GENRES);
+
+                    context.runOnUiThread(new Runnable() {
+                        @Override
+                        public void run() {
+                            // Refresh the fast scroll data, since SectionIndexer doesn't respect notifyDataSetChanged
+                            int[] lists = {R.id.artists_list, R.id.albums_list, R.id.songs_list, R.id.genres_list};
+                            if (getView() != null) {
+                                ListView l;
+                                for (int r : lists) {
+                                    l = (ListView) getView().findViewById(r);
+                                    l.setFastScrollEnabled(false);
+                                    l.setFastScrollEnabled(true);
+                                }
+                            }
+                            focusHelper(false, R.id.artists_list);
+                        }
+                    });
+                }
+            }).start();
         }
-        focusHelper(listId == MODE_TOTAL, lists[listId]);
     }
 
     AudioBrowserListAdapter.ContextPopupMenuListener mContextPopupMenuListener
diff --git a/vlc-android/src/org/videolan/vlc/gui/audio/AudioBrowserListAdapter.java b/vlc-android/src/org/videolan/vlc/gui/audio/AudioBrowserListAdapter.java
index c8e7cbb..082f343 100644
--- a/vlc-android/src/org/videolan/vlc/gui/audio/AudioBrowserListAdapter.java
+++ b/vlc-android/src/org/videolan/vlc/gui/audio/AudioBrowserListAdapter.java
@@ -22,18 +22,22 @@ package org.videolan.vlc.gui.audio;
 
 import java.util.ArrayList;
 import java.util.HashMap;
+import java.util.LinkedList;
 import java.util.List;
 import java.util.Locale;
 import java.util.Map;
 
 import org.videolan.libvlc.Media;
 import org.videolan.vlc.R;
+import org.videolan.vlc.gui.MainActivity;
 import org.videolan.vlc.util.BitmapCache;
 import org.videolan.vlc.util.Util;
 
+import android.app.Activity;
 import android.content.Context;
 import android.content.SharedPreferences;
 import android.graphics.Bitmap;
+import android.os.Looper;
 import android.preference.PreferenceManager;
 import android.util.SparseArray;
 import android.view.LayoutInflater;
@@ -49,6 +53,11 @@ import android.widget.TextView;
 public class AudioBrowserListAdapter extends BaseAdapter implements SectionIndexer {
     public final static String TAG = "VLC/AudioBrowserListAdapter";
 
+    public final static int TYPE_ARTISTS = 0;
+    public final static int TYPE_ALBUMS = 1;
+    public final static int TYPE_SONGS = 2;
+    public final static int TYPE_GENRES = 3;
+
     // Key: the item title, value: ListItem of only media item (no separator).
     private Map<String, ListItem> mMediaItemMap;
     private Map<String, ListItem> mSeparatorItemMap;
@@ -59,7 +68,7 @@ public class AudioBrowserListAdapter extends BaseAdapter implements SectionIndex
 
     private int mAlignMode; // align mode from prefs
 
-    private Context mContext;
+    private Activity mContext;
 
     // The types of the item views: media and separator.
     private static final int VIEW_MEDIA = 0;
@@ -89,7 +98,7 @@ public class AudioBrowserListAdapter extends BaseAdapter implements SectionIndex
         }
     }
 
-    public AudioBrowserListAdapter(Context context, int itemType) {
+    public AudioBrowserListAdapter(Activity context, int itemType) {
         mMediaItemMap = new HashMap<String, ListItem>();
         mSeparatorItemMap = new HashMap<String, ListItem>();
         mItems = new ArrayList<ListItem>();
@@ -113,7 +122,47 @@ public class AudioBrowserListAdapter extends BaseAdapter implements SectionIndex
             mMediaItemMap.put(title, item);
             mItems.add(item);
         }
-        notifyDataSetChanged();
+    }
+
+    public void addAll(List<Media> mediaList, final int type) {
+        final LinkedList<Media> list = new LinkedList<Media>(mediaList);
+        mContext.runOnUiThread(new Runnable() {
+            @Override
+            public void run() {
+                String title, subTitle;
+                for (Media media : list) {
+                    switch (type){
+                        case TYPE_ALBUMS:
+                            title = media.getAlbum();
+                            subTitle = media.getArtist();
+                            break;
+                        case TYPE_ARTISTS:
+                            title = media.getArtist();
+                            subTitle = null;
+                            break;
+                        case TYPE_GENRES:
+                            title = media.getGenre();
+                            subTitle = null;
+                            break;
+                        case TYPE_SONGS:
+                        default:
+                            title = media.getTitle();
+                            subTitle = media.getArtist();
+                    }
+                    if (title == null) return;
+                    title = title.trim();
+                    if (subTitle != null) subTitle = subTitle.trim();
+                    if (mMediaItemMap.containsKey(title))
+                        mMediaItemMap.get(title).mMediaList.add(media);
+                    else {
+                        ListItem item = new ListItem(title, subTitle, media, false);
+                        mMediaItemMap.put(title, item);
+                        mItems.add(item);
+                    }
+                }
+                addLetterSeparators();
+            }
+        });
     }
 
     public void addLetterSeparators() {
-- 
1.9.1



More information about the Android mailing list