从互联网上检索图像

时间:2013-12-27 13:17:30

标签: java android

我从“Android in Practice”一书中获得了以下代码。它是从互联网上下载图像的自定义适配器的实现。它使用私有类RetrieveImageTask来检索图片。

有人可以解释一下为什么适配器类的第一件事就是从缓存中获取图像而不是下载它?我以第一次显示的方式理解它 默认图像是在getView()的开头设置的,然后设置下载的图像,但它是否意味着通过调用getView()不断刷新视图?

为什么作者将图片标记设置为getView()中的商品ID,然后将其设置为null中的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);
     }
  }

}

2 个答案:

答案 0 :(得分:1)

它称为延迟加载。好的图像需要时间从网上下载,因此设置了一些虚拟图像。随着下载完成,它将替换为虚拟图像。基本上是应用程序的用户体验问题。

答案 1 :(得分:1)

标记与代码的缓存机制如何工作有关 - 项目的关键是此示例中的数字,这意味着它用于标识下载了哪个图像,以便您可以从缓存中加载它而不是来自互联网。

我同意这很奇怪,因为它可以简单地放置图像的网址。使用url更合乎逻辑。

示例效率不高,因为它不使用viewHolder设计模式(您可以通过“listView世界”讲座了解它)并且没有考虑下采样(您可以查看{ {3}}关于它。)

显示正确图像之前显示的图像用于向用户显示正在准备的图像(如占位符说“正在下载...”)。

这只是一个供您学习的样本。