package com.koushikdutta.urlimageviewhelper.sample;
import java.io.ByteArrayOutputStream;
import java.io.DataInputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Hashtable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import android.app.Activity;
import android.content.Context;
import android.database.DataSetObserver;
import android.graphics.Bitmap;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.view.Menu;
import android.view.MenuItem;
import android.view.MenuItem.OnMenuItemClickListener;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.Adapter;
import android.widget.ArrayAdapter;
import android.widget.BaseAdapter;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.ListView;
import com.android.volley.VolleyError;
import com.android.volley.toolbox.ImageLoader;
import com.android.volley.toolbox.Volley;
import com.androidquery.AQuery;
import com.androidquery.callback.AjaxStatus;
import com.androidquery.callback.BitmapAjaxCallback;
import com.koushikdutta.async.AsyncServer;
import com.koushikdutta.async.http.AsyncHttpClient;
import com.koushikdutta.async.http.AsyncHttpGet;
import com.koushikdutta.async.http.AsyncHttpResponse;
import com.koushikdutta.async.http.ResponseCacheMiddleware;
import com.koushikdutta.urlimageviewhelper.UrlDownloader;
import com.koushikdutta.urlimageviewhelper.UrlImageViewCallback;
import com.koushikdutta.urlimageviewhelper.UrlImageViewHelper;
import com.nostra13.universalimageloader.core.ImageLoaderConfiguration;
import com.nostra13.universalimageloader.core.assist.FailReason;
import com.nostra13.universalimageloader.core.assist.ImageLoadingListener;
import com.squareup.picasso.LruCache;
import com.squareup.picasso.Picasso;
import com.squareup.picasso.Transformation;
public class UrlImageViewHelperSample extends Activity {
// turn a stream into a string
private static String readToEnd(InputStream input) throws IOException
{
DataInputStream dis = new DataInputStream(input);
byte[] stuff = new byte[1024];
ByteArrayOutputStream buff = new ByteArrayOutputStream();
int read = 0;
while ((read = dis.read(stuff)) != -1)
{
buff.write(stuff, 0, read);
}
return new String(buff.toByteArray());
}
private ListView mListView;
private MyAdapter mAdapter;
private class Row extends ArrayList {
}
private class MyGridAdapter extends BaseAdapter {
public MyGridAdapter(Adapter adapter) {
mAdapter = adapter;
mAdapter.registerDataSetObserver(new DataSetObserver() {
@Override
public void onChanged() {
super.onChanged();
notifyDataSetChanged();
}
@Override
public void onInvalidated() {
super.onInvalidated();
notifyDataSetInvalidated();
}
});
}
Adapter mAdapter;
@Override
public int getCount() {
return (int)Math.ceil((double)mAdapter.getCount() / 4d);
}
@Override
public Row getItem(int position) {
Row row = new Row();
for (int i = position * 4; i < 4; i++) {
if (mAdapter.getCount() < i)
row.add(mAdapter.getItem(i));
else
row.add(null);
}
return row;
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
convertView = getLayoutInflater().inflate(R.layout.row, null);
LinearLayout row = (LinearLayout)convertView;
LinearLayout l = (LinearLayout)row.getChildAt(0);
for (int child = 0; child < 4; child++) {
int i = position * 4 + child;
LinearLayout c = (LinearLayout)l.getChildAt(child);
c.removeAllViews();
if (i < mAdapter.getCount()) {
c.addView(mAdapter.getView(i, null, null));
}
}
return convertView;
}
}
long start;
private class MyAdapter extends ArrayAdapter<String> {
public MyAdapter(Context context) {
super(context, 0);
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
if (convertView == null)
convertView = getLayoutInflater().inflate(R.layout.image, null);
final ImageView iv = (ImageView)convertView.findViewById(R.id.image);
loader.load(getItem(position), iv);
return convertView;
}
}
private static interface AbstractImageLoader {
public void load(String url, ImageView iv);
public void clear();
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuItem legacy = menu.add("UrlImage");
legacy.setOnMenuItemClickListener(new OnMenuItemClickListener() {
@Override
public boolean onMenuItemClick(MenuItem item) {
UrlImageViewHelper.getDownloaders().remove(downloader);
loader = UrlImageViewHelperSample.this.koush;
return true;
}
});
MenuItem koush = menu.add("UrlImage+Async");
koush.setOnMenuItemClickListener(new OnMenuItemClickListener() {
@Override
public boolean onMenuItemClick(MenuItem item) {
UrlImageViewHelper.getDownloaders().remove(downloader);
UrlImageViewHelper.getDownloaders().add(0, downloader);
loader = UrlImageViewHelperSample.this.koush;
return true;
}
});
MenuItem volley = menu.add("Volley");
volley.setOnMenuItemClickListener(new OnMenuItemClickListener() {
@Override
public boolean onMenuItemClick(MenuItem item) {
loader = UrlImageViewHelperSample.this.volley;
return true;
}
});
MenuItem picasso = menu.add("Picasso");
picasso.setOnMenuItemClickListener(new OnMenuItemClickListener() {
@Override
public boolean onMenuItemClick(MenuItem item) {
loader = UrlImageViewHelperSample.this.picasso;
return true;
}
});
MenuItem universal = menu.add("Universal");
universal.setOnMenuItemClickListener(new OnMenuItemClickListener() {
@Override
public boolean onMenuItemClick(MenuItem item) {
loader = UrlImageViewHelperSample.this.universal;
return true;
}
});
MenuItem aquery = menu.add("AQuery");
aquery.setOnMenuItemClickListener(new OnMenuItemClickListener() {
@Override
public boolean onMenuItemClick(MenuItem item) {
UrlImageViewHelper.getDownloaders().remove(downloader);
loader = UrlImageViewHelperSample.this.aquery;
return true;
}
});
MenuItem clear = menu.add("clear caches");
clear.setOnMenuItemClickListener(new OnMenuItemClickListener() {
@Override
public boolean onMenuItemClick(MenuItem item) {
mAdapter.clear();
UrlImageViewHelperSample.this.aquery.clear();
UrlImageViewHelperSample.this.universal.clear();
UrlImageViewHelperSample.this.picasso.clear();
UrlImageViewHelperSample.this.koush.clear();
UrlImageViewHelperSample.this.volley.clear();
deleteDirectory(getFilesDir());
deleteDirectory(new File(getCacheDir(), "volley"));
deleteDirectory(new File(getCacheDir(), "sample"));
deleteDirectory(new File(getCacheDir(), "picasso-cache"));
deleteDirectory(new File(getCacheDir(), "aquery"));
return true;
}
});
return super.onCreateOptionsMenu(menu);
}
AbstractImageLoader volley;
private void updateTime() {
if (Looper.myLooper() == null) {
runOnUiThread(new Runnable() {
@Override
public void run() {
// TODO Auto-generated method stub
updateTime();
}
});
return;
}
setTitle("" + (System.currentTimeMillis() - start) + "ms");
}
AbstractImageLoader koush = new AbstractImageLoader() {
@Override
public void load(String url, ImageView iv) {
UrlImageViewHelper.setUrlDrawable(iv, url, R.drawable.loading, new UrlImageViewCallback() {
@Override
public void onLoaded(ImageView imageView, Bitmap loadedBitmap, String url, boolean loadedFromCache) {
updateTime();
}
});
}
@Override
public void clear() {
UrlImageViewHelper.clear(UrlImageViewHelperSample.this);
try {
rcache.clear();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
};
AbstractImageLoader universal = new AbstractImageLoader() {
@Override
public void load(String url, ImageView iv) {
com.nostra13.universalimageloader.core.ImageLoader.getInstance().displayImage(url, iv, new ImageLoadingListener() {
@Override
public void onLoadingCancelled(String arg0, View arg1) {
// TODO Auto-generated method stub
}
@Override
public void onLoadingComplete(String arg0, View arg1,
Bitmap arg2) {
updateTime();
}
@Override
public void onLoadingFailed(String arg0, View arg1,
FailReason arg2) {
updateTime();
}
@Override
public void onLoadingStarted(String arg0, View arg1) {
// TODO Auto-generated method stub
}
});
}
@Override
public void clear() {
com.nostra13.universalimageloader.core.ImageLoader.getInstance().clearDiscCache();
com.nostra13.universalimageloader.core.ImageLoader.getInstance().clearMemoryCache();
}
};
AbstractImageLoader aquery = new AbstractImageLoader() {
@Override
public void load(String url, ImageView iv) {
BitmapAjaxCallback cb = new BitmapAjaxCallback() {
@Override
protected void callback(String url, ImageView iv, Bitmap bm,
AjaxStatus status) {
updateTime();
super.callback(url, iv, bm, status);
}
@Override
public Bitmap getResult() {
return super.getResult();
}
};
cb.url(url);
new AQuery(iv).image(cb);
}
@Override
public void clear() {
BitmapAjaxCallback.clearCache();
}
};
AbstractImageLoader picasso = new AbstractImageLoader() {
@Override
public void load(String url, ImageView iv) {
Picasso.with(UrlImageViewHelperSample.this).load(url)
.resize(128, 128) // under the hood, urlimageviewhelper also resizes the image too. picasso hits a oom without this.
.transform(new Transformation() {
@Override
public Bitmap transform(Bitmap arg0) {
updateTime();
return arg0;
}
@Override
public String key() {
return "timer";
}
}).into(iv);
}
@Override
public void clear() {
try {
Field cache = Picasso.class.getDeclaredField("cache");
cache.setAccessible(true);
LruCache plru = (LruCache)cache.get(Picasso.with(UrlImageViewHelperSample.this));
plru.evictAll();
}
catch (Exception e) {
e.printStackTrace();
}
}
};
static public boolean deleteDirectory(File path) {
try {
if (path.exists()) {
File[] files = path.listFiles();
if (files != null) {
for (int i = 0; i < files.length; i++) {
if (files[i].isDirectory()) {
deleteDirectory(files[i]);
} else {
files[i].delete();
}
}
}
}
return (path.delete());
}
catch (Exception e) {
return false;
}
}
AbstractImageLoader loader = koush;
ResponseCacheMiddleware rcache;
UrlDownloader downloader;
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
com.nostra13.universalimageloader.core.ImageLoader.getInstance().init(ImageLoaderConfiguration.createDefault(this));
volley = new AbstractImageLoader() {
Hashtable<String, Bitmap> hash = new Hashtable<String, Bitmap>();
ImageLoader volley = new ImageLoader(Volley.newRequestQueue(UrlImageViewHelperSample.this), new ImageLoader.ImageCache() {
@Override
public Bitmap getBitmap(String url) {
return hash.get(url);
}
@Override
public void putBitmap(String url, Bitmap bitmap) {
hash.put(url, bitmap);
}
});
@Override
public void load(String url, final ImageView iv) {
volley.get(url, new ImageLoader.ImageListener() {
@Override
public void onResponse(ImageLoader.ImageContainer response, boolean isImmediate) {
if (response.getBitmap() != null) {
iv.setImageBitmap(response.getBitmap());
updateTime();
}
else {
iv.setImageResource(R.drawable.loading);
}
}
@Override
public void onErrorResponse(VolleyError error) {
iv.setImageResource(R.drawable.loading);
updateTime();
}
});
}
@Override
public void clear() {
hash.clear();
}
};
// UrlImageViewHelper doesn't use AndroidAsync out of the box. It uses HttpUrlConnection.
// Plug in a downloader to use AndroidAsync.
final AsyncHttpClient client = new AsyncHttpClient(new AsyncServer());
final Handler handler = new Handler();
// match picasso's thread pool size.
final ExecutorService exec = Executors.newFixedThreadPool(3);
UrlImageViewHelper.getDownloaders().add(0, downloader = new UrlDownloader() {
final UrlDownloader self = this;
@Override
public void download(Context context, String url, final String filename, final UrlDownloaderCallback callback, final Runnable completion) {
AsyncHttpGet get = new AsyncHttpGet(url);
get.setHandler(null);
client.execute(get, filename, new AsyncHttpClient.FileCallback() {
@Override
public void onCompleted(Exception e, AsyncHttpResponse source, File result) {
assert(Looper.myLooper() == null);
if (e == null) {
exec.execute(new Runnable() {
@Override
public void run() {
callback.onDownloadComplete(self, null, filename);
handler.post(completion);
}
});
return;
}
handler.post(completion);
}
});
}
@Override
public boolean allowCache() {
return false;
}
@Override
public boolean canDownloadUrl(String url) {
return true;
}
});
try {
rcache = ResponseCacheMiddleware.addCache(client, new File(getCacheDir(), "sample"), 24L * 1024L * 1024L);
}
catch (Exception e) {
}
setContentView(R.layout.main);
final Button search = (Button)findViewById(R.id.search);
mListView = (ListView)findViewById(R.id.results);
mAdapter = new MyAdapter(this);
MyGridAdapter a = new MyGridAdapter(mAdapter);
mListView.setAdapter(a);
search.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
mAdapter.clear();
start = System.currentTimeMillis();
for (int i = 0; i < 40; i++) {
mAdapter.add("https://raw.github.com/koush/dogs/master/" + i + ".jpg");
}
}
});
}
}