Search code examples
androidperformancelistviewimage-loading

ListView VERY slow when images are loaded (using Universal Image Loader)


My listView runs very smooth with just text - but as soon as I try to load in thumbnails (even from cache), it runs SOO choppy.

I'm using the Universal Image Loader script

The code in my ArticleEntryAdapter within public View getView(...) method:

/**
     * PHOTOS
     */
    ImageLoaderConfiguration config = new ImageLoaderConfiguration.Builder(this.mContext)
        .enableLogging()
        .memoryCacheSize(41943040)
        .discCacheSize(104857600)
        .threadPoolSize(10)
        .build();

    DisplayImageOptions imgDisplayOptions = new DisplayImageOptions.Builder()
        //.showStubImage(R.drawable.stub_image)
        .cacheInMemory() 
        .cacheOnDisc() 
        //.imageScaleType(ImageScaleType.EXACT) 
        .build();

    ImageLoader imageLoader = ImageLoader.getInstance();
    imageLoader.init(config);

    //loads image (or hides image area)
    imageLoader.displayImage("", viewHolder.thumbView); //clears previous one
    if(article.photopath != null && article.photopath.length() != 0)
    {
        imageLoader.displayImage(
            "http://img.mysite.com/processes/resize_android.php?image=" + article.photopath + "&size=150&quality=80",
            viewHolder.thumbView,
            imgDisplayOptions
            );
        viewHolder.thumbView.setVisibility(View.VISIBLE);
    }
    else
    {
        viewHolder.thumbView.setVisibility(View.GONE); //hide image
        viewHolder.thumbView.invalidate(); //should call after changing to GONE
    }

Logcat shows that it's loading the images from cache (I think):

ImageLoader    Load image from memory cache [http://img.mysite.com/processes/...

I'm testing it on my Samsung Galaxy Nexus and running Android 4.0.4 (though my minSdkVersion="8")


Solution

  • Put the instantation of ImageLoaderConfiguration config, DisplayImageOptions imgDisplayOptions, ImageLoader imageLoader outside of your getView method as private fields/members of your Adapter class. You should only have create these things once, not everytime getView is called.

    Edit : without seeing your whole Adapter class, here a stab at what I'm saying. I hope its close to what you have and you can make it work out. Lemme know either way.

    public class MyAdapterClass extends BaseAdapter {
        /**
         * PHOTOS
         */
        static ImageLoaderConfiguration config = new ImageLoaderConfiguration.Builder(this.mContext)
            .enableLogging()
            .memoryCacheSize(41943040)
            .discCacheSize(104857600)
            .threadPoolSize(10)
            .build();
    
        static DisplayImageOptions imgDisplayOptions = new DisplayImageOptions.Builder()
            //.showStubImage(R.drawable.stub_image)
            .cacheInMemory() 
            .cacheOnDisc() 
            //.imageScaleType(ImageScaleType.EXACT) 
            .build();
    
        static ImageLoader imageLoader = ImageLoader.getInstance();
        /**
         * 
         */
        public MyAdapterClass() {
            // TODO Auto-generated constructor stub
            imageLoader.init(config);           
        }
    
        /* (non-Javadoc)
         * @see android.widget.Adapter#getCount()
         */
        public int getCount() {
            // TODO Auto-generated method stub
            return 0;
        }
    
        /* (non-Javadoc)
         * @see android.widget.Adapter#getItem(int)
         */
        public Object getItem(int position) {
            // TODO Auto-generated method stub
            return null;
        }
    
        /* (non-Javadoc)
         * @see android.widget.Adapter#getItemId(int)
         */
        public long getItemId(int position) {
            // TODO Auto-generated method stub
            return 0;
        }
    
        /* (non-Javadoc)
         * @see android.widget.Adapter#getView(int, android.view.View, android.view.ViewGroup)
         */
        public View getView(int position, View convertView, ViewGroup parent) {
            //loads image (or hides image area)
            imageLoader.displayImage("", viewHolder.thumbView); //clears previous one
            if(article.photopath != null && article.photopath.length() != 0)
            {
                imageLoader.displayImage(
                    "http://img.mysite.com/processes/resize_android.php?image=" + article.photopath + "&size=150&quality=80",
                    viewHolder.thumbView,
                    imgDisplayOptions
                    );
                viewHolder.thumbView.setVisibility(View.VISIBLE);
            }
            else
            {
                viewHolder.thumbView.setVisibility(View.GONE); //hide image
                viewHolder.thumbView.invalidate(); //should call after changing to GONE
            }
        }
    
    }