/*
* *************************************************************************
* 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.databinding.OnRebindCallback;
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;
import java.util.concurrent.Callable;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
public class AsyncImageLoader {
public interface Callbacks {
Bitmap getImage();
void updateImage(Bitmap bitmap, View target);
}
public final static String TAG = "VLC/AsyncImageLoader";
/* Maximum one thread that is killed after 2 seconds of inactivity */
static ThreadPoolExecutor sThreadPool = new ThreadPoolExecutor(0, 1, 2, TimeUnit.SECONDS,
new LinkedBlockingQueue<Runnable>());
public static void LoadImage(final Callbacks cbs, final View target){
sThreadPool.execute(new Runnable() {
@Override
public void run() {
final Bitmap bitmap = cbs.getImage();
cbs.updateImage(bitmap, target);
}
});
}
public static void LoadAudioCover(final Callable<Bitmap> loader, final ViewDataBinding binding, final Activity activity){
final Callbacks updater = new Callbacks() {
@Override
public Bitmap getImage() {
try {
return loader.call();
} catch (Exception ignored) {
return null;
}
}
@Override
public void updateImage(final Bitmap bitmap, View target) {
if (bitmap != null && activity != null) {
activity.runOnUiThread(new Runnable() {
@Override
public void run() {
binding.setVariable(BR.cover, new BitmapDrawable(VLCApplication.getAppResources(), bitmap));
binding.executePendingBindings();
}
});
}
}
};
LoadImage(updater, null);
}
public abstract static class CoverFetcher implements AsyncImageLoader.Callbacks {
final protected ViewDataBinding binding;
private boolean bindChanged = false;
final OnRebindCallback<ViewDataBinding> rebindCallbacks = new OnRebindCallback<ViewDataBinding>() {
@Override
public boolean onPreBind(ViewDataBinding binding) {
bindChanged = true;
return super.onPreBind(binding);
}
@Override
public void onCanceled(ViewDataBinding binding) {
super.onCanceled(binding);
}
@Override
public void onBound(ViewDataBinding binding) {
super.onBound(binding);
}
};
protected CoverFetcher(ViewDataBinding binding){
this.binding = binding;
this.binding.addOnRebindCallback(rebindCallbacks);
}
public abstract void updateBindImage(final Bitmap bitmap, View target);
@Override
public final void updateImage(final Bitmap bitmap, View target) {
this.binding.removeOnRebindCallback(rebindCallbacks);
if (!bindChanged)
updateBindImage(bitmap, target);
}
}
}