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

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

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

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

  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 пользовательского адаптера

 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 ответа

Вы действительно должны принять Reinvent the wheel близко к сердцу, но если вы действительно хотите научиться, подход может быть:

  1. используйте ThreadPoolExecutor, чтобы получить больше изображений одновременно, вы должны прочитать, как их использовать
  2. реализовать способ отменить потоки, которые загружают img для griditem, который больше не отображается
  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 и вызвать метод отображения соответствующим образом.

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