[Android] Async image loading for TV

Geoffrey Métais git at videolan.org
Mon Sep 7 16:12:03 CEST 2015


vlc-ports/android | branch: master | Geoffrey Métais <geoffrey.metais at gmail.com> | Mon Sep  7 16:11:38 2015 +0200| [a965e88ecb9c40783492cdc540586ec93076dac0] | committer: Geoffrey Métais

Async image loading for TV

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

 .../src/org/videolan/vlc/gui/AsyncImageLoader.java |   62 +++++++++++-------
 .../vlc/gui/audio/AudioBrowserListAdapter.java     |    2 +-
 .../src/org/videolan/vlc/gui/tv/CardPresenter.java |   66 ++++++++++++++------
 3 files changed, 87 insertions(+), 43 deletions(-)

diff --git a/vlc-android/src/org/videolan/vlc/gui/AsyncImageLoader.java b/vlc-android/src/org/videolan/vlc/gui/AsyncImageLoader.java
index fd5df92..d634251 100644
--- a/vlc-android/src/org/videolan/vlc/gui/AsyncImageLoader.java
+++ b/vlc-android/src/org/videolan/vlc/gui/AsyncImageLoader.java
@@ -27,6 +27,7 @@ import android.app.Activity;
 import android.databinding.ViewDataBinding;
 import android.graphics.Bitmap;
 import android.graphics.drawable.BitmapDrawable;
+import android.view.View;
 
 import org.videolan.vlc.BR;
 import org.videolan.vlc.VLCApplication;
@@ -38,37 +39,52 @@ 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 interface ImageUpdater {
+        void updateImage(Bitmap bitmap, View target);
+    }
 
-    public static void LoadImage(Callable<Bitmap> loader, final ViewDataBinding binding, Activity activity){
+    public final static String TAG = "VLC/AsyncImageLoader";
 
-        Future<Bitmap> future = executor.submit(loader);
-        handleImage(binding, activity, future);
-    }
+    static ExecutorService executor = Executors.newSingleThreadExecutor();
 
-    private static void handleImage(final ViewDataBinding binding, final Activity activity, final Future<Bitmap> future) {
+    public static void LoadImage(Callable<Bitmap> loader, final ImageUpdater updater, final View target){
+        final Future<Bitmap> future = executor.submit(loader);
         new Thread(new Runnable() {
             @Override
             public void run() {
-                try {
-                    final Bitmap bitmap = future.get();
-                    if (activity != null) {
-                        activity.runOnUiThread(new Runnable() {
-                            @Override
-                            public void run() {
-                                binding.setVariable(BR.cover, new BitmapDrawable(VLCApplication.getAppResources(), bitmap));
-                                binding.executePendingBindings();
-                            }
-                        });
-                    }
-                } catch (InterruptedException e) {
-                    e.printStackTrace();
-                } catch (ExecutionException e) {
-                    e.printStackTrace();
-                }
+                handleImage(updater, future, target);
             }
         }).start();
     }
+
+    public static void LoadAudioCover(Callable<Bitmap> loader, final ViewDataBinding binding, final Activity activity){
+        ImageUpdater updater = new ImageUpdater() {
+            @Override
+            public void updateImage(final Bitmap bitmap, View target) {
+                if (activity != null) {
+                    activity.runOnUiThread(new Runnable() {
+                        @Override
+                        public void run() {
+                            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();
+            updater.updateImage(bitmap, target);
+        } catch (InterruptedException e) {
+            e.printStackTrace();
+        } catch (ExecutionException e) {
+            e.printStackTrace();
+        }
+    }
 }
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 a2bc098..004fa38 100644
--- a/vlc-android/src/org/videolan/vlc/gui/audio/AudioBrowserListAdapter.java
+++ b/vlc-android/src/org/videolan/vlc/gui/audio/AudioBrowserListAdapter.java
@@ -329,7 +329,7 @@ public class AudioBrowserListAdapter extends BaseAdapter implements SectionIndex
 
         if (mItemType == ITEM_WITH_COVER) {
             AudioUtil.AudioCoverFetcher fetcher = new AudioUtil.AudioCoverFetcher(mContext, mItems.get(position).mMediaList);
-            AsyncImageLoader.LoadImage(fetcher, holder.binding, mContext);
+            AsyncImageLoader.LoadAudioCover(fetcher, holder.binding, mContext);
         }
 
         holder.binding.setVariable(BR.footer, !isMediaItemAboveASeparator(position));
diff --git a/vlc-android/tv/src/org/videolan/vlc/gui/tv/CardPresenter.java b/vlc-android/tv/src/org/videolan/vlc/gui/tv/CardPresenter.java
index 7f8d5a4..9b2e5fd 100644
--- a/vlc-android/tv/src/org/videolan/vlc/gui/tv/CardPresenter.java
+++ b/vlc-android/tv/src/org/videolan/vlc/gui/tv/CardPresenter.java
@@ -23,8 +23,8 @@ package org.videolan.vlc.gui.tv;
 import org.videolan.vlc.MediaDatabase;
 import org.videolan.vlc.MediaWrapper;
 import org.videolan.vlc.R;
+import org.videolan.vlc.gui.AsyncImageLoader;
 import org.videolan.vlc.gui.audio.AudioUtil;
-import org.videolan.vlc.gui.tv.browser.GridFragment;
 import org.videolan.vlc.gui.tv.browser.MusicFragment;
 import org.videolan.vlc.util.BitmapUtil;
 
@@ -40,6 +40,8 @@ import android.view.View;
 import android.view.ViewGroup;
 import android.widget.ImageView;
 
+import java.util.concurrent.Callable;
+
 public class CardPresenter extends Presenter {
 
     private static final String TAG = "CardPresenter";
@@ -72,24 +74,8 @@ public class CardPresenter extends Presenter {
         }
 
         protected void updateCardViewImage(MediaWrapper mediaWrapper) {
-                mCardView.getMainImageView().setScaleType(ImageView.ScaleType.CENTER);
-            Bitmap picture = null;
-            if (mediaWrapper.getType() == mediaWrapper.TYPE_AUDIO) {
-                picture = AudioUtil.getCover(sContext, mediaWrapper, 320);
-                if (picture == null)
-                    picture = BitmapFactory.decodeResource(mRes, R.drawable.ic_browser_audio_big_normal);
-            } else if (mediaWrapper.getType() == mediaWrapper.TYPE_VIDEO) {
-                picture = BitmapUtil.getPictureFromCache(mediaWrapper);
-                if (picture == null)
-                    picture = BitmapFactory.decodeResource(mRes, R.drawable.ic_browser_video_big_normal);
-            } else if (mediaWrapper.getType() == mediaWrapper.TYPE_DIR)
-                picture = BitmapFactory.decodeResource(mRes, R.drawable.ic_menu_network_big);
-            else
-                picture = BitmapFactory.decodeResource(mRes, R.drawable.ic_browser_unknown_big_normal);
-            if (picture != null && picture.getByteCount() > 4)
-                mCardView.setMainImage(new BitmapDrawable(mRes, picture));
-            else
-                mCardView.setMainImage(sDefaultCardImage);
+            mCardView.getMainImageView().setScaleType(ImageView.ScaleType.CENTER);
+            AsyncImageLoader.LoadImage(new CoverFetcher(mediaWrapper), sImageUpdater, mCardView);
         }
 
         protected void updateCardViewImage(Drawable image) {
@@ -181,4 +167,46 @@ public class CardPresenter extends Presenter {
             this.name = name;
         }
     }
+
+    public static class CoverFetcher implements Callable<Bitmap>{
+        MediaWrapper mediaWrapper;
+
+        CoverFetcher(MediaWrapper mediaWrapper){
+            this.mediaWrapper = mediaWrapper;
+        }
+
+        @Override
+        public Bitmap call() throws Exception {
+            Bitmap picture = null;
+            if (mediaWrapper.getType() == mediaWrapper.TYPE_AUDIO) {
+                picture = AudioUtil.getCover(sContext, mediaWrapper, 320);
+                if (picture == null)
+                    picture = BitmapFactory.decodeResource(mRes, R.drawable.ic_browser_audio_big_normal);
+            } else if (mediaWrapper.getType() == mediaWrapper.TYPE_VIDEO) {
+                picture = BitmapUtil.getPictureFromCache(mediaWrapper);
+                if (picture == null)
+                    picture = BitmapFactory.decodeResource(mRes, R.drawable.ic_browser_video_big_normal);
+            } else if (mediaWrapper.getType() == mediaWrapper.TYPE_DIR)
+                picture = BitmapFactory.decodeResource(mRes, R.drawable.ic_menu_network_big);
+            else
+                picture = BitmapFactory.decodeResource(mRes, R.drawable.ic_browser_unknown_big_normal);
+            return picture;
+        }
+    }
+
+    public static AsyncImageLoader.ImageUpdater sImageUpdater = new AsyncImageLoader.ImageUpdater() {
+        @Override
+        public void updateImage(final Bitmap picture, final View target) {
+            target.post(new Runnable() {
+                @Override
+                public void run() {
+                    ImageCardView cardView = (ImageCardView) target;
+                    if (picture != null && picture.getByteCount() > 4)
+                        cardView.setMainImage(new BitmapDrawable(mRes, picture));
+                    else
+                        cardView.setMainImage(sDefaultCardImage);
+                }
+            });
+        }
+    };
 }



More information about the Android mailing list