【问题标题】:What is the right coding about Image Loading?关于图像加载的正确编码是什么?
【发布时间】:2018-04-11 09:34:20
【问题描述】:

我正在解决关于 Image Loader 的问题,但我遇到了一些问题..

  1. 我想要在 GridView(或 ListView)中显示许多图像(大约 400 张)。
  2. 我不想像 Picasso、Glide 那样使用图书馆。

这就是问题所在。

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

  2. 有两件事运行良好。但是太慢了...可能是因为调用 URLConnection 的时间..

谁能帮我解决这些问题?我怎样才能加快速度?或者是否有任何其他没有开源的解决方案。

这是我的来源。

现在,3-1。

显示图像

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;
}

【问题讨论】:

  • 您必须通过 Glide 或 Picasso 加载所有图像。为什么要从 URL 获取位图?
  • 如何加快速度? - 使用您不想使用的图像加载库之一,而不是在同一线程上按顺序获取所有图像
  • @Rujul Gandhi 我知道图书馆让我很舒服。但这是项目,重要的一个是任何人都没有使用图书馆lile Glide或毕加索..所以这对我来说是个问题..
  • 你的项目中添加了 Glide 依赖了吗?
  • @Rujul Gandhi 是的。我添加了毕加索。即使速度很好,也能很好地工作。但我想要的是让项目成为任何图书馆..

标签: android imageloader


【解决方案1】:

你真的应该把 Reinventing the wheel 放在心上,但如果你真的想折磨自己,一个方法可能是:

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

【讨论】:

    【解决方案2】:

    不要使用 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 方法。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-01-19
      • 2020-04-17
      • 1970-01-01
      • 1970-01-01
      • 2018-11-24
      • 2019-05-17
      相关资源
      最近更新 更多