Ok, I've been trying to optimize my photo gallery for days now (this is my first Android project). All photos are loaded via Web page. I've started using Universal Image Loader, but I'm still not content with results.
Here's my class:
public class Galerija extends Activity {
ArrayList<RSSItem> lista = new ArrayList<RSSItem>();
ArrayList<String> lst_slika = new ArrayList<String>();
RSSItem tempItem = new RSSItem();
ImageAdapter adapter;
ImageLoader imageLoader;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_galerija);
try
{
SAXParserFactory spf = SAXParserFactory.newInstance();
SAXParser sp = spf.newSAXParser();
XMLReader myReader = sp.getXMLReader();
URL url = new URL("http://erdut.gausstesting.info/generateXML/galerija.php");
XMLHandler myXMLHandler = new XMLHandler();
myReader.setContentHandler(myXMLHandler);
myReader.parse(new InputSource(url.openStream()));
lista = myXMLHandler.getRss_lista();
lst_slika = lista.get(0).getImages();
} catch (Exception e) {
System.out.println(e);
}
adapter = new ImageAdapter(this, lst_slika);
GridView gridview = (GridView) findViewById(R.id.gridview);
gridview.setAdapter(adapter);
gridview.setOnItemClickListener(new OnItemClickListener() {
public void onItemClick(AdapterView<?> arg0, View arg1, int arg2,
long arg3) {
// TODO Auto-generated method stub
}
});
}
public class ImageAdapter extends BaseAdapter {
private Context mContext;
private ArrayList<String> lista;
/*
final ImageLoaderConfiguration config = new ImageLoaderConfiguration.Builder(this.mContext)
.enableLogging()
.memoryCacheSize(41943040)
.discCacheSize(104857600)
.threadPoolSize(10)
.build();
*/
final DisplayImageOptions options = new DisplayImageOptions.Builder()
.showStubImage(R.drawable.ic_stub)
.showImageForEmptyUri(R.drawable.ic_empty)
.showImageOnFail(R.drawable.ic_error)
.cacheInMemory()
.cacheOnDisc()
.build();
public ImageAdapter(Context c, ArrayList<String> lista) {
this.mContext = c;
this.lista = lista;
imageLoader = ImageLoader.getInstance();
//imageLoader.init(config);
imageLoader.init(ImageLoaderConfiguration.createDefault(c));
}
public int getCount() {
return lista.size();
}
public Object getItem(int position) {
return null;
}
public long getItemId(int position) {
return 0;
}
// create a new ImageView for each item referenced by the Adapter
public View getView(int position, View convertView, ViewGroup parent) {
ImageView imageView;
if (convertView == null) { // if it's not recycled, initialize some attributes
imageView = new ImageView(mContext);
//ova 3 polja označavaju veličinu, cropanje i padding prikazanih slika
imageView.setLayoutParams(new GridView.LayoutParams(150, 150));
imageView.setScaleType(ImageView.ScaleType.CENTER_CROP);
imageView.setPadding(0, 0, 0, 0);
} else {
imageView = (ImageView) convertView;
}
imageLoader.displayImage(lista.get(position), imageView, options);
//new ImageDownloadTask(imageView).execute(lista.get(position));
return imageView;
}
}
}
It has definitely sped things up compared to my previous solution, but I'm not content. First of all, I can't even start it on my HTC Incredible S - Just starts an activity with black screen and nothing loads. Why is that?
It only works on emulator, but it reloads all the images as you scroll. So, once you've scrolled down and then back up, all images appear to be reloaded. Is that how it's suppose to work? Any further ways I can improve this?
Thanks in advance!
You should consider using asynctask to get urls from the server.
You use should be using a view holder for smooth scrolling and performance. http://www.youtube.com/watch?v=wDBM6wVEO70. The talk is about view holder and listview performance.
http://developer.android.com/training/improving-layouts/smooth-scrolling.html
https://github.com/nostra13/Android-Universal-Image-Loader. Check the topic under Configuration and Display Options.
Instead of downloading it again you should cache images in phone memory or sdcard.
It caches images in say sdcard (if you have configured properly) using url as the key. If present display from cache else download, cache and display images.
In your custom adapter constructor
File cacheDir = StorageUtils.getOwnCacheDirectory(activity context, "your folder");//for caching
// Get singletone instance of ImageLoader
imageLoader = ImageLoader.getInstance();
// Create configuration for ImageLoader (all options are optional)
ImageLoaderConfiguration config = new ImageLoaderConfiguration.Builder(a)
// You can pass your own memory cache implementation
.discCache(new UnlimitedDiscCache(cacheDir)) // You can pass your own disc cache implementation
.discCacheFileNameGenerator(new HashCodeFileNameGenerator())
.enableLogging()
.build();
// Initialize ImageLoader with created configuration. Do it once.
imageLoader.init(config);
options = new DisplayImageOptions.Builder()
.cacheInMemory(true)
.cacheOnDisk(true)
.showImageOnLoading(R.drawable.default_pic)//display stub image until image is loaded
.displayer(new RoundedBitmapDisplayer(20))
.build();
In your getView()
viewholder.image=(ImageView)vi.findViewById(R.id.imageview);
imageLoader.displayImage(imageurl, viewholder.image,options);//provide imageurl, imageview and options.