views:

83

answers:

3

I use in the getView()-Method of this example a static function to download the source of an ImageView. Later there will be threading included. However, I like to know in general how save the use of static function is in this case.

Because I experienced, that in some cases (when I scroll really fast) the Images get mixed up.

    /**
    * Is called, when the ListAdapter requests a new ListItem, when scrolling. Returns a listItem (row)
    */
        public View getView(int position, View convertView, ViewGroup parent) {
                        View v = convertView;
                        if (v == null) {
                            LayoutInflater vi = (LayoutInflater)getSystemService(Context.LAYOUT_INFLATER_SERVICE);
                            v = vi.inflate(R.layout.row, null);
                        }
                        Order o = items.get(position);
                        if (o != null) {
                                TextView tt = (TextView) v.findViewById(R.id.toptext);

                                if (tt != null) {
                                      tt.setText("Name: "+o.getOrderName());                            }

//At this point I use a static function to download the bitmap to set it as source of an ImageView

                        }
                        return v;
                }
A: 

If a static function has no side-effects, then it should be perfectly safe to use. Based on your description of the function, it does seem to have side effects, so you need to make sure that calling the function from different places doesn't cause any conflicts. I can't really tell you anything more without seeing the function.

Mike Baranczak
+2  A: 

I use in the getView()-Method of this example a static function to download the source of an ImageView.

I do not see a static method anywhere in that blog post.

Because I experienced, that in some cases (when I scroll really fast) the Images get mixed up.

That has nothing to do with the method being static, and everything to do with applying the images. Rows get recycled. Hence, if a download of an image takes too long, it may be that the image is no longer needed -- the ImageView should be showing some other image instead. One way to address this is to stick the URL of the image needed by an ImageView in setTag() on the ImageView itself. When the download is complete, before putting the downloaded image in the ImageView, call getTag() and compare URLs. If the URL in the tag is different than the URL that was downloaded, do not update the ImageView, since that will be for the wrong image.

CommonsWare
+1  A: 

I fixed this by not reusing the renderers (it really sounds more painfull than it is) but instead "caching" them using an array with WeakReference objects. This makes your list fast and prevents you from setting images on renderers that are now used for other data, while at the same time giving the GC a chance to remove the unused list items if you run low on memory.

public View getView(int position, View convertView, ViewGroup parent) {
    Renderer result = null;
    WeakReference<Renderer> wr = (WeakReference<Renderer>) _renderers[position];
    if (ref != null)
        result = wr.get();

    if (result == null) {
        result = new Renderer(_context);
        // set the texts here and start loading your images
        _renderers[position] = new WeakReference<Renderer>(result);
    }
    return result;
}

You have to cast _renderers[position] to WeakReference, because java does not support arrays with generics, so _renderers is an array of Objects

Thomas Vervest
I will consider ur answer and give feedback, when Im done with it.
OneWorld