[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