[Android] Async audio cover loading

Geoffrey Métais git at videolan.org
Mon Sep 7 14:29:23 CEST 2015


vlc-ports/android | branch: master | Geoffrey Métais <geoffrey.metais at gmail.com> | Mon Sep  7 13:58:58 2015 +0200| [2895e77046cfa7f7049f61d486c0559dca88d1e0] | committer: Geoffrey Métais

Async audio cover loading

> http://git.videolan.org/gitweb.cgi/vlc-ports/android.git/?a=commit;h=2895e77046cfa7f7049f61d486c0559dca88d1e0
---

 .../src/org/videolan/vlc/gui/AsyncImageLoader.java |   73 ++++++++++++++++++++
 .../vlc/gui/audio/AudioBrowserListAdapter.java     |   22 +++---
 .../src/org/videolan/vlc/gui/audio/AudioUtil.java  |   36 +++++++++-
 3 files changed, 116 insertions(+), 15 deletions(-)

diff --git a/vlc-android/src/org/videolan/vlc/gui/AsyncImageLoader.java b/vlc-android/src/org/videolan/vlc/gui/AsyncImageLoader.java
new file mode 100644
index 0000000..f147660
--- /dev/null
+++ b/vlc-android/src/org/videolan/vlc/gui/AsyncImageLoader.java
@@ -0,0 +1,73 @@
+/*
+ * *************************************************************************
+ *  AsyncImageLoader.java
+ * **************************************************************************
+ *  Copyright © 2015 VLC authors and VideoLAN
+ *  Author: Geoffrey Métais
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
+ *  ***************************************************************************
+ */
+
+package org.videolan.vlc.gui;
+
+import android.app.Activity;
+import android.graphics.Bitmap;
+import android.widget.ImageView;
+
+import java.util.concurrent.Callable;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.Future;
+
+public class AsyncImageLoader {
+    public final static String TAG = "VLC/AsyncImageLoader";
+
+    static ExecutorService executor = Executors.newSingleThreadExecutor();
+
+    public static void LoadImage(Callable<Bitmap> loader, final ImageView view, Activity activity){
+
+        Future<Bitmap> future = executor.submit(loader);
+        handleImage(view, activity, future);
+    }
+
+    private static void handleImage(final ImageView view, final Activity activity, final Future<Bitmap> future) {
+        new Thread(new Runnable() {
+            @Override
+            public void run() {
+                try {
+                    final Bitmap bitmap = future.get();
+
+                    activity.runOnUiThread(new Runnable() {
+                        @Override
+                        public void run() {
+                            view.post(new Runnable() {
+                                @Override
+                                public void run() {
+                                    view.setImageBitmap(bitmap);
+                                }
+                            });
+                        }
+                    });
+                } catch (InterruptedException e) {
+                    e.printStackTrace();
+                } catch (ExecutionException e) {
+                    e.printStackTrace();
+                }
+            }
+        }).start();
+    }
+}
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 97911d9..5d133df 100644
--- a/vlc-android/src/org/videolan/vlc/gui/audio/AudioBrowserListAdapter.java
+++ b/vlc-android/src/org/videolan/vlc/gui/audio/AudioBrowserListAdapter.java
@@ -28,6 +28,8 @@ import android.databinding.DataBindingUtil;
 import android.databinding.ViewDataBinding;
 import android.graphics.Bitmap;
 import android.graphics.drawable.BitmapDrawable;
+import android.os.Handler;
+import android.os.Message;
 import android.preference.PreferenceManager;
 import android.support.v4.util.ArrayMap;
 import android.util.Log;
@@ -45,6 +47,7 @@ import org.videolan.vlc.BR;
 import org.videolan.vlc.MediaWrapper;
 import org.videolan.vlc.R;
 import org.videolan.vlc.interfaces.IAudioClickHandler;
+import org.videolan.vlc.gui.AsyncImageLoader;
 import org.videolan.vlc.util.BitmapCache;
 import org.videolan.vlc.util.Util;
 
@@ -55,6 +58,7 @@ import java.util.LinkedList;
 import java.util.List;
 import java.util.Locale;
 import java.util.Map;
+import java.util.concurrent.Callable;
 
 public class AudioBrowserListAdapter extends BaseAdapter implements SectionIndexer, IAudioClickHandler {
     public final static String TAG = "VLC/AudioBrowserListAdapter";
@@ -332,20 +336,10 @@ public class AudioBrowserListAdapter extends BaseAdapter implements SectionIndex
         holder.binding.setVariable(BR.item, item);
 
         if (mItemType == ITEM_WITH_COVER) {
-            Bitmap cover = null;
-            LinkedList<String> testedAlbums = new LinkedList<String>();
-            for (MediaWrapper media : mItems.get(position).mMediaList) {
-                if (media.getAlbum() != null && testedAlbums.contains(media.getAlbum()))
-                    continue;
-                cover = AudioUtil.getCover(v.getContext(), media, 64);
-                if (cover != null)
-                    break;
-                else if (media.getAlbum() != null)
-                    testedAlbums.add(media.getAlbum());
-            }
-            if (cover == null)
-                cover = BitmapCache.getFromResource(v, R.drawable.icon);
-            holder.binding.setVariable(BR.cover, new BitmapDrawable(mContext.getResources(), cover));
+            AudioUtil.AudioCoverFetcher fetcher = new AudioUtil.AudioCoverFetcher(mContext, mItems.get(position).mMediaList);
+            AsyncImageLoader.LoadImage(fetcher, holder.cover, mContext);
+            //TODO
+            //holder.binding.setVariable(BR.cover, new BitmapDrawable(mContext.getResources(), cover));
         }
 
         holder.binding.setVariable(BR.footer, !isMediaItemAboveASeparator(position));
diff --git a/vlc-android/src/org/videolan/vlc/gui/audio/AudioUtil.java b/vlc-android/src/org/videolan/vlc/gui/audio/AudioUtil.java
index d10f5e5..a5a4582 100644
--- a/vlc-android/src/org/videolan/vlc/gui/audio/AudioUtil.java
+++ b/vlc-android/src/org/videolan/vlc/gui/audio/AudioUtil.java
@@ -59,7 +59,10 @@ import java.io.UnsupportedEncodingException;
 import java.math.BigInteger;
 import java.security.MessageDigest;
 import java.security.NoSuchAlgorithmException;
+import java.util.ArrayList;
 import java.util.Arrays;
+import java.util.LinkedList;
+import java.util.concurrent.Callable;
 
 public class AudioUtil {
     public final static String TAG = "VLC/AudioUtil";
@@ -360,7 +363,8 @@ public class AudioUtil {
 
         /* Get the resolution of the bitmap without allocating the memory */
         options.inJustDecodeBounds = true;
-        options.inMutable = true;
+        if (AndroidUtil.isHoneycombOrLater())
+            options.inMutable = true;
         BitmapUtil.setInBitmap(options);
         BitmapFactory.decodeFile(path, options);
 
@@ -379,4 +383,34 @@ public class AudioUtil {
 
         return cover;
     }
+
+    public static class AudioCoverFetcher implements Callable<Bitmap> {
+
+        ArrayList<MediaWrapper> list;
+        Context context;
+
+        AudioCoverFetcher(Context context, ArrayList<MediaWrapper> list){
+            this.list = list;
+            this.context = context;
+        }
+
+        @Override
+        public Bitmap call() throws Exception {
+            Bitmap cover = null;
+            LinkedList<String> testedAlbums = new LinkedList<String>();
+            for (MediaWrapper media : list) {
+                if (media.getAlbum() != null && testedAlbums.contains(media.getAlbum()))
+                    continue;
+
+                cover = AudioUtil.getCover(context, media, 64);
+                if (cover != null)
+                    break;
+                else if (media.getAlbum() != null)
+                    testedAlbums.add(media.getAlbum());
+            }
+            if (cover == null)
+                cover = BitmapCache.getFromResource(context.getResources(), R.drawable.icon);
+            return cover;
+        }
+    }
 }



More information about the Android mailing list