有关图像加载的正确编码是什么?

时间:2018-04-11 09:34:20

标签: android imageloader

我解决了Image Loader的问题,我遇到了一些问题。

  1. 我想要的是在GridView(或ListView)中显示许多图像(大约400个)。
  2. 我不想像Picasso那样使用图书馆,Glide就是这样。
  3. 以下是问题所在。

    1. 当我调用从url转换为位图的方法时?
      3.1。在setAdapter之前,然后传递位图数组 3.2。而getView。

    2. 两件事情都运作良好。但是太慢了......也许是时候调用URLConnection ..

    3. 有人可以帮我解决这些问题吗?我怎样才能加快速度?或者没有开源的任何其他解决方案。

      这是我的来源。

      现在,3-1。

      ShowImage

      private void showImages(ArrayList<String> imgUrls) {
          ArrayList<Bitmap> bitmaps = new ArrayList<>();
          for (int i = 0; i < imgUrls.size(); i++) {
              try {
                  String img_path = imgUrls.get(i);
                  Bitmap bitmap = new UriToBitmapAsyncTask().execute(img_path).get();
                  bitmaps.add(bitmap);
              } catch (Exception e) {
                  Toast.makeText(this, e.getMessage(), Toast.LENGTH_SHORT).show();
              }
          }
          CustomAdapter adapter = new CustomAdapter(getApplicationContext(),R.layout.row,bitmaps);
      
          gridView.setAdapter(adapter);
      }
      

      这是customAdapter的GetView

       public View getView(int position, View convertView, ViewGroup parent) {
          ViewHolder viewHolder;
      
          if (convertView == null) {
              convertView = inflator.inflate(rowLayout, parent, false);
      
              viewHolder = new ViewHolder();
              viewHolder.imageView = (ImageView) convertView.findViewById(R.id.imageView);
      
              convertView.setTag(viewHolder);
          } else {
              viewHolder = (ViewHolder) convertView.getTag();
          }
          viewHolder.imageView.setImageBitmap(bitmaps.get(position));
          return convertView;
      }
      

2 个答案:

答案 0 :(得分:0)

你应该把Reinventing the wheel铭记于心,但如果你真的想要自己动手,那么方法可能是:

  1. 使用ThreadPoolExecutor一次获取更多图像,你应该阅读如何使用它们
  2. 实现一种方法来取消为不再显示的griditem加载img的线程
  3. 使用两组数据,一个缩略图加载网格视图,一个真实图像,当用户点击网格时加载
  4. 不要忘记使用LRU缓存方法,否则您的设备将耗尽内存(具体取决于图像)

答案 1 :(得分:0)

不要使用ArrayList来存储位图。位图通常占用大量内存。尝试像这样使用LRUCache,

public class TCImageLoader implements ComponentCallbacks2 {
private TCLruCache cache;

public TCImageLoader(Context context) {
    ActivityManager am = (ActivityManager) context.getSystemService(
        Context.ACTIVITY_SERVICE);
    int maxKb = am.getMemoryClass() * 1024;
    int limitKb = maxKb / 8; // 1/8th of total ram
    cache = new TCLruCache(limitKb);
}

public void display(String url, ImageView imageview, int defaultresource) {
    imageview.setImageResource(defaultresource);
    Bitmap image = cache.get(url);
    if (image != null) {
        imageview.setImageBitmap(image);
    }
    else {
        new SetImageTask(imageview).execute(url);
    }
}

private class TCLruCache extends LruCache<String, Bitmap> {

    public TCLruCache(int maxSize) {
        super(maxSize);
    }

    @Override
    protected int sizeOf(ImagePoolKey key, Bitmap value) {
        int kbOfBitmap = value.getByteCount() / 1024;
        return kbOfBitmap;
    }
}

private class SetImageTask extends AsyncTask<String, Void, Integer> {
    private ImageView imageview;
    private Bitmap bmp;

    public SetImageTask(ImageView imageview) {
        this.imageview = imageview;
    }

    @Override
    protected Integer doInBackground(String... params) {
        String url = params[0];
        try {
            bmp = getBitmapFromURL(url);
            if (bmp != null) {
                cache.put(url, bmp);
            }
            else {
                return 0;
            }
        } catch (Exception e) {
            e.printStackTrace();
            return 0;
        }
        return 1;
    }

    @Override
    protected void onPostExecute(Integer result) {
        if (result == 1) {
            imageview.setImageBitmap(bmp);
        }
        super.onPostExecute(result);
    }

    private Bitmap getBitmapFromURL(String src) {
        try {
            URL url = new URL(src);
            HttpURLConnection connection
                = (HttpURLConnection) url.openConnection();
            connection.setDoInput(true);
            connection.connect();
            InputStream input = connection.getInputStream();
            Bitmap myBitmap = BitmapFactory.decodeStream(input);
            return myBitmap;
        } catch (IOException e) {
            e.printStackTrace();
            return null;
        }
    }

}

@Override
public void onConfigurationChanged(Configuration newConfig) {
}

@Override
public void onLowMemory() {
}

@Override
public void onTrimMemory(int level) {
    if (level >= TRIM_MEMORY_MODERATE) {
        cache.evictAll();
    }
    else if (level >= TRIM_MEMORY_BACKGROUND) {
        cache.trimToSize(cache.size() / 2);
    }
}
}

获取TCImageLoader的实例并适当调用display方法。