Как правильно кодировать загрузку изображений?

Я решаю свою проблему с Image Loader и у меня проблемы ..

  1. Я хочу показать много изображений (около 400) в GridView (или ListView).
  2. Я не хочу использовать Библиотеку как Пикассо, как это Glide.

и вот в чем проблема.

  1. Когда я вызываю метод преобразования URL в растровое изображение?
    3.1. перед setAdapter, затем передайте массив растровых изображений. 3.2. а getView.

  2. две вещи работают хорошо. но слишком медленно ... может быть, из-за того, что нужно вызывать URLConnection ..

Может ли кто-нибудь помочь мне с этой проблемой? Как я могу ускориться? или есть какое-нибудь другое решение без Open Source.

Вот мой Источник.

Теперь 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);
}

и это GetView customAdapter

 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 11.04.2018 11:37
Как я могу ускориться? - используйте одну из тех библиотек загрузки изображений, которые вы не хотите использовать, вместо последовательной загрузки всех изображений в одном потоке
Tim 11.04.2018 11:41

@ Руджул Ганди Я знаю, что в библиотеке мне комфортно. но это проект, и одним из важных является то, что никто не должен использовать библиотеку lile Glide или Picasso .. так что это проблема для меня ..

Adrian 11.04.2018 11:45

Вы добавили в свой проект зависимость Glide?

Rujul Gandhi 11.04.2018 11:48

@ Руджул Ганди ага. Я добавил Picasso. И работает очень хорошо, даже скорость хорошая. но я хочу, чтобы проект находился в любой библиотеке.

Adrian 11.04.2018 11:52

Я не вижу ни одной причины, по которой нельзя использовать готовую библиотеку.

Vladyslav Matviienko 11.04.2018 11:59
0
6
39
2

Ответы 2

Вам действительно стоит принять Изобретая колесо близко к сердцу, но если вы действительно хотите проявить себя, подход может быть следующим:

  1. используйте ThreadPoolExecutor для одновременной загрузки большего количества изображений, вы должны прочитать, как их использовать
  2. реализовать способ отмены потоков, которые загружают img для элемента сетки, который больше не отображается
  3. использовать два набора данных: эскиз, который загружается быстрее для представления сетки, и реальное изображение, которое загружается, когда пользователь нажимает на сетку
  4. не забудьте использовать метод кэширования LRU, иначе на вашем устройстве не хватит памяти в зависимости от изображений.

Не используйте 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 и соответствующим образом вызвать метод отображения.

Другие вопросы по теме