[Android] Async image loading for video thumbs

Geoffrey Métais git at videolan.org
Wed Sep 9 12:03:26 CEST 2015


vlc-ports/android | branch: master | Geoffrey Métais <geoffrey.metais at gmail.com> | Wed Sep  9 12:02:38 2015 +0200| [f186cb941d4fde9c784100344a00b6a714518aa1] | committer: Geoffrey Métais

Async image loading for video thumbs

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

 .../src/org/videolan/vlc/gui/AsyncImageLoader.java |   22 ++++++++++++
 .../videolan/vlc/gui/video/VideoListAdapter.java   |   38 ++++++++++++--------
 .../src/org/videolan/vlc/util/BitmapCache.java     |    3 +-
 3 files changed, 47 insertions(+), 16 deletions(-)

diff --git a/vlc-android/src/org/videolan/vlc/gui/AsyncImageLoader.java b/vlc-android/src/org/videolan/vlc/gui/AsyncImageLoader.java
index 76a6e9c..ccf6210 100644
--- a/vlc-android/src/org/videolan/vlc/gui/AsyncImageLoader.java
+++ b/vlc-android/src/org/videolan/vlc/gui/AsyncImageLoader.java
@@ -28,6 +28,7 @@ import android.databinding.ViewDataBinding;
 import android.graphics.Bitmap;
 import android.graphics.drawable.BitmapDrawable;
 import android.view.View;
+import android.widget.ImageView;
 
 import org.videolan.vlc.BR;
 import org.videolan.vlc.VLCApplication;
@@ -77,6 +78,27 @@ public class AsyncImageLoader {
         LoadImage(loader, updater, null);
     }
 
+    public static void LoadVideoCover(Callable<Bitmap> loader, final ViewDataBinding binding, final Activity activity){
+        ImageUpdater updater = new ImageUpdater() {
+            @Override
+            public void updateImage(final Bitmap bitmap, View target) {
+                if (bitmap != null && activity != null &&
+                        (bitmap.getWidth() != 1 && bitmap.getHeight() != 1)) {
+                    activity.runOnUiThread(new Runnable() {
+                        @Override
+                        public void run() {
+                            binding.setVariable(BR.scaleType, ImageView.ScaleType.FIT_CENTER);
+                            binding.setVariable(BR.cover, new BitmapDrawable(VLCApplication.getAppResources(), bitmap));
+                            binding.executePendingBindings();
+                        }
+                    });
+                }
+
+            }
+        };
+        LoadImage(loader, updater, null);
+    }
+
     private static void handleImage(final ImageUpdater updater, final Future<Bitmap> future, View target){
         try {
             final Bitmap bitmap = future.get();
diff --git a/vlc-android/src/org/videolan/vlc/gui/video/VideoListAdapter.java b/vlc-android/src/org/videolan/vlc/gui/video/VideoListAdapter.java
index e6784a4..0bf7234 100644
--- a/vlc-android/src/org/videolan/vlc/gui/video/VideoListAdapter.java
+++ b/vlc-android/src/org/videolan/vlc/gui/video/VideoListAdapter.java
@@ -37,12 +37,15 @@ import org.videolan.vlc.BR;
 import org.videolan.vlc.MediaGroup;
 import org.videolan.vlc.MediaWrapper;
 import org.videolan.vlc.R;
+import org.videolan.vlc.VLCApplication;
+import org.videolan.vlc.gui.AsyncImageLoader;
 import org.videolan.vlc.util.BitmapCache;
 import org.videolan.vlc.util.BitmapUtil;
 import org.videolan.vlc.util.Strings;
 
 import java.util.Comparator;
 import java.util.Locale;
+import java.util.concurrent.Callable;
 
 public class VideoListAdapter extends ArrayAdapter<MediaWrapper>
                                  implements Comparator<MediaWrapper> {
@@ -55,6 +58,8 @@ public class VideoListAdapter extends ArrayAdapter<MediaWrapper>
     private boolean mListMode = false;
     private VideoGridFragment mFragment;
 
+    public static final BitmapDrawable DEFAULT_COVER = new BitmapDrawable(VLCApplication.getAppResources(), BitmapCache.getFromResource(VLCApplication.getAppResources(), R.drawable.ic_cone_o));
+
     public VideoListAdapter(VideoGridFragment fragment) {
         super(fragment.getActivity(), 0);
         mFragment = fragment;
@@ -178,21 +183,10 @@ public class VideoListAdapter extends ArrayAdapter<MediaWrapper>
 
         MediaWrapper media = getItem(position);
 
-        /* Thumbnail */
-        Bitmap thumbnail = BitmapUtil.getPictureFromCache(media);
-        if (thumbnail == null) {
-            // missing thumbnail
-            holder.binding.setVariable(BR.scaleType, ImageView.ScaleType.CENTER);
-            thumbnail = BitmapCache.getFromResource(v.getResources(), R.drawable.ic_cone_o);
-        } else if (thumbnail.getWidth() == 1 && thumbnail.getHeight() == 1) {
-            // dummy thumbnail
-            holder.binding.setVariable(BR.scaleType, ImageView.ScaleType.CENTER);
-            thumbnail = BitmapCache.getFromResource(v.getResources(), R.drawable.ic_cone_o);
-        } else
-            holder.binding.setVariable(BR.scaleType, ImageView.ScaleType.FIT_CENTER);
-
-        //FIXME Warning: the thumbnails are upscaled in the grid view!
-        holder.binding.setVariable(BR.cover, new BitmapDrawable(getContext().getResources(), thumbnail));
+        AsyncImageLoader.LoadVideoCover(new VideoCoverFetcher(media), holder.binding, mFragment.getActivity());
+
+        holder.binding.setVariable(BR.scaleType, ImageView.ScaleType.CENTER);
+        holder.binding.setVariable(BR.cover, DEFAULT_COVER);
 
         if (media instanceof MediaGroup)
             fillGroupView(holder, media);
@@ -261,4 +255,18 @@ public class VideoListAdapter extends ArrayAdapter<MediaWrapper>
     public boolean isListMode() {
         return mListMode;
     }
+
+    public static class VideoCoverFetcher implements Callable<Bitmap> {
+
+        MediaWrapper media;
+
+        VideoCoverFetcher(MediaWrapper media){
+            this.media = media;
+        }
+
+        @Override
+        public Bitmap call() throws Exception {
+            return BitmapUtil.getPictureFromCache(media);
+        }
+    }
 }
diff --git a/vlc-android/src/org/videolan/vlc/util/BitmapCache.java b/vlc-android/src/org/videolan/vlc/util/BitmapCache.java
index 19af888..a836361 100644
--- a/vlc-android/src/org/videolan/vlc/util/BitmapCache.java
+++ b/vlc-android/src/org/videolan/vlc/util/BitmapCache.java
@@ -47,6 +47,7 @@ public class BitmapCache {
     private final static boolean LOG_ENABLED = false;
 
     private static final String CONE_KEY = "res:"+ R.drawable.cone;
+    private static final String CONE_O_KEY = "res:"+ R.drawable.ic_cone_o;
     private static BitmapCache mInstance;
     private final LruCache<String, CacheableBitmap> mMemCache;
     Set<SoftReference<Bitmap>> mCachedBitmaps;
@@ -83,7 +84,7 @@ public class BitmapCache {
             protected void entryRemoved(boolean evicted, String key, CacheableBitmap oldValue, CacheableBitmap newValue) {
                 if (evicted) {
                     mCachedBitmaps.remove(oldValue.getReference());
-                    if (oldValue.get() != null && !TextUtils.equals(key, CONE_KEY))
+                    if (oldValue.get() != null && !TextUtils.equals(key, CONE_KEY) && !TextUtils.equals(key, CONE_O_KEY))
                         addReusableBitmapRef(oldValue.getReference());
                 }
             }



More information about the Android mailing list