1

I've got the following code from "Android in Practice" book. It's implementation of custom adapter which downloads images from the internet. It uses private class RetrieveImageTask to retrieve pictures.

Can someone explain me why the first thing the adapter class does is to get image from the cache instead of downloading it ? I understand it in a way that, the first time it displays default image which was set in the beginning of getView(), then sets downloaded image, but does it mean that view is being refreshed constantly by calling getView() ?

And why author sets tag of image to item ID in getView() and then sets it to null in onPostExecute() ?

DealsAdapter

private class DealsAdapter extends ArrayAdapter<Item> {      

  public DealsAdapter(List<Item> items) {
     super(DealList.this, R.layout.list_item, items);
  }

  @Override
  public View getView(int position, View convertView, ViewGroup parent) {

     if (convertView == null) {
        LayoutInflater inflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        convertView = inflater.inflate(R.layout.list_item, parent, false);
     }

     // use ViewHolder here to prevent multiple calls to findViewById (if you have a large collection)
     TextView text = (TextView) convertView.findViewById(R.id.deal_title);
     ImageView image = (ImageView) convertView.findViewById(R.id.deal_img);
     image.setImageBitmap(BitmapFactory.decodeResource(getResources(), R.drawable.ddicon));

     Item item = getItem(position);

     if (item != null) {
        text.setText(item.getTitle());
        Bitmap bitmap = app.getImageCache().get(item.getItemId()); //<------HERE
        if (bitmap != null) {
           image.setImageBitmap(bitmap);
        } else {
           // put item ID on image as TAG for use in task
           image.setTag(item.getItemId());
           // separate thread/via task, for retrieving each image
           // (note that this is brittle as is, should stop all threads in onPause)               
           new RetrieveImageTask(image).execute(item.getSmallPicUrl());
        }
     }
     return convertView;
  }
}

RetriveImageTask

private class RetrieveImageTask extends AsyncTask<String, Void, Bitmap> {
  private ImageView imageView;

  public RetrieveImageTask(ImageView imageView) {
     this.imageView = imageView;
  }

  @Override
  protected Bitmap doInBackground(String... args) {
     Bitmap bitmap = app.retrieveBitmap(args[0]);
     return bitmap;
  }

  @Override
  protected void onPostExecute(Bitmap bitmap) {
     if (bitmap != null) {
        imageView.setImageBitmap(bitmap);
        app.getImageCache().put((Long) imageView.getTag(), bitmap);
        imageView.setTag(null);
     }
  }

}

ashur
  • 4,177
  • 14
  • 53
  • 85

2 Answers2

1

Its called lazy loading. well images take time to download from net so by that some dummy image is set. As the downloading completes it will replaced with dummy image. Basically is matter of user experience with application.

Sush
  • 3,864
  • 2
  • 17
  • 35
1

the tag has something to do with how the cache mechanism of your code works- the key of the items is their number in this sample , meaning it is used to identify which image was downloaded so that you could load it from the cache instead of from the internet.

i agree that it's weird, as it could simply put the url of the image instead. using the url is more logical .

the sample isn't so efficient as it doesn't use the viewHolder design pattern (you can learn about it via the lecture "the world of listView") and doesn't have downsampling in mind (you can check out this post about it).

the image that is shown before showing the correct image is for showing the user that it's being prepared (like a placeholder saying "downloading...").

it's just a sample for you to learn from.

Community
  • 1
  • 1
android developer
  • 114,585
  • 152
  • 739
  • 1,270