Ленивая загрузка изображений в ListView

Это работает для меня.

jQuery("#form_name").validate().settings.ignore = "";
1856
задан Pehlaj 28 April 2017 в 11:59
поделиться

5 ответов

Вот то, что я создал для содержания изображений, которые в настоящее время отображает мое приложение. Обратите внимание на то, что объект "Журнала", используемый вот, является моей пользовательской оберткой вокруг заключительного класса Журнала в Android.

package com.wilson.android.library;

/*
 Licensed to the Apache Software Foundation (ASF) under one or more
contributor license agreements.  See the NOTICE file
distributed with this work for additional information
regarding copyright ownership.  The ASF licenses this file
to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance
with the License.  You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express or implied.  See the License for the
specific language governing permissions and limitations
under the License.
*/
import java.io.IOException;

public class DrawableManager {
    private final Map<String, Drawable> drawableMap;

    public DrawableManager() {
        drawableMap = new HashMap<String, Drawable>();
    }

    public Drawable fetchDrawable(String urlString) {
        if (drawableMap.containsKey(urlString)) {
            return drawableMap.get(urlString);
        }

        Log.d(this.getClass().getSimpleName(), "image url:" + urlString);
        try {
            InputStream is = fetch(urlString);
            Drawable drawable = Drawable.createFromStream(is, "src");


            if (drawable != null) {
                drawableMap.put(urlString, drawable);
                Log.d(this.getClass().getSimpleName(), "got a thumbnail drawable: " + drawable.getBounds() + ", "
                        + drawable.getIntrinsicHeight() + "," + drawable.getIntrinsicWidth() + ", "
                        + drawable.getMinimumHeight() + "," + drawable.getMinimumWidth());
            } else {
              Log.w(this.getClass().getSimpleName(), "could not get thumbnail");
            }

            return drawable;
        } catch (MalformedURLException e) {
            Log.e(this.getClass().getSimpleName(), "fetchDrawable failed", e);
            return null;
        } catch (IOException e) {
            Log.e(this.getClass().getSimpleName(), "fetchDrawable failed", e);
            return null;
        }
    }

    public void fetchDrawableOnThread(final String urlString, final ImageView imageView) {
        if (drawableMap.containsKey(urlString)) {
            imageView.setImageDrawable(drawableMap.get(urlString));
        }

        final Handler handler = new Handler() {
            @Override
            public void handleMessage(Message message) {
                imageView.setImageDrawable((Drawable) message.obj);
            }
        };

        Thread thread = new Thread() {
            @Override
            public void run() {
                //TODO : set imageView to a "pending" image
                Drawable drawable = fetchDrawable(urlString);
                Message message = handler.obtainMessage(1, drawable);
                handler.sendMessage(message);
            }
        };
        thread.start();
    }

    private InputStream fetch(String urlString) throws MalformedURLException, IOException {
        DefaultHttpClient httpClient = new DefaultHttpClient();
        HttpGet request = new HttpGet(urlString);
        HttpResponse response = httpClient.execute(request);
        return response.getEntity().getContent();
    }
}
1067
ответ дан Zoe the transgirl 28 April 2017 в 21:59
поделиться

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

Этот метод не работает очень хорошо при переработке представлений как бы то ни было.

40
ответ дан jasonhudgins 28 April 2017 в 21:59
поделиться

Обновление: обратите внимание, что этот ответ сейчас довольно неэффективен. Сборщик мусора агрессивно действует на SoftReference и WeakReference, поэтому этот код НЕ подходит для новых приложений. (Вместо этого попробуйте библиотеки вроде Universal Image Loader , предложенные в других ответах.)

Спасибо Джеймсу за код и Бао-Луну за предложение использовать SoftReference. Я внес изменения SoftReference в код Джеймса. К сожалению, SoftReferences заставил мои изображения слишком быстро собрать мусор. В моем случае все было нормально без материала SoftReference, потому что размер моего списка ограничен, а мои изображения маленькие.

Год назад было обсуждение SoftReferences в группах Google: ссылка на ветку . В качестве решения слишком ранней сборки мусора они предлагают возможность вручную установить размер кучи виртуальной машины с помощью dalvik.system.VMRuntime.setMinimumHeapSize (), что для меня не очень привлекательно.

public DrawableManager() {
    drawableMap = new HashMap<String, SoftReference<Drawable>>();
}

public Drawable fetchDrawable(String urlString) {
    SoftReference<Drawable> drawableRef = drawableMap.get(urlString);
    if (drawableRef != null) {
        Drawable drawable = drawableRef.get();
        if (drawable != null)
            return drawable;
        // Reference has expired so remove the key from drawableMap
        drawableMap.remove(urlString);
    }

    if (Constants.LOGGING) Log.d(this.getClass().getSimpleName(), "image url:" + urlString);
    try {
        InputStream is = fetch(urlString);
        Drawable drawable = Drawable.createFromStream(is, "src");
        drawableRef = new SoftReference<Drawable>(drawable);
        drawableMap.put(urlString, drawableRef);
        if (Constants.LOGGING) Log.d(this.getClass().getSimpleName(), "got a thumbnail drawable: " + drawable.getBounds() + ", "
                + drawable.getIntrinsicHeight() + "," + drawable.getIntrinsicWidth() + ", "
                + drawable.getMinimumHeight() + "," + drawable.getMinimumWidth());
        return drawableRef.get();
    } catch (MalformedURLException e) {
        if (Constants.LOGGING) Log.e(this.getClass().getSimpleName(), "fetchDrawable failed", e);
        return null;
    } catch (IOException e) {
        if (Constants.LOGGING) Log.e(this.getClass().getSimpleName(), "fetchDrawable failed", e);
        return null;
    }
}

public void fetchDrawableOnThread(final String urlString, final ImageView imageView) {
    SoftReference<Drawable> drawableRef = drawableMap.get(urlString);
    if (drawableRef != null) {
        Drawable drawable = drawableRef.get();
        if (drawable != null) {
            imageView.setImageDrawable(drawableRef.get());
            return;
        }
        // Reference has expired so remove the key from drawableMap
        drawableMap.remove(urlString);
    }

    final Handler handler = new Handler() {
        @Override
        public void handleMessage(Message message) {
            imageView.setImageDrawable((Drawable) message.obj);
        }
    };

    Thread thread = new Thread() {
        @Override
        public void run() {
            //TODO : set imageView to a "pending" image
            Drawable drawable = fetchDrawable(urlString);
            Message message = handler.obtainMessage(1, drawable);
            handler.sendMessage(message);
        }
    };
    thread.start();
}
106
ответ дан 22 November 2019 в 20:02
поделиться

Я сделал простую демонстрацию ленивого списка (размещенного на GitHub) с изображениями.

Основное использование

 ImageLoader imageLoader = новый ImageLoader (контекст); ...
imageLoader.DisplayImage (url, imageView);

Не забудьте добавить следующие разрешения для вашего AndroidManifest.xml:

  
  Пожалуйста

создайте только один экземпляр ImageLoader и повторно используйте его во всех своих заявление. Таким образом, кеширование изображений будет намного более эффективным.

Это может быть кому-то полезно. Он загружает изображения в фоновом потоке. Изображения кэшируются на SD-карту и в память.Реализация кеша очень проста, и этого достаточно для демонстрации. Я декодирую изображения с помощью inSampleSize, чтобы уменьшить потребление памяти. Я также стараюсь правильно обрабатывать переработанные виды.

Alt text

1018
ответ дан 22 November 2019 в 20:02
поделиться

Многопоточность для повышения производительности , учебное пособие Жиля Дебанна.

Это из блога разработчиков Android. Предлагаемый код использует:

  • AsyncTasks .
  • Жесткий, ограниченный размер, кэш FIFO .
  • Мягкий, простой сборщик мусора кэш.
  • Заполнитель Возможность рисования при загрузке.

enter image description here

155
ответ дан 22 November 2019 в 20:02
поделиться
Другие вопросы по тегам:

Похожие вопросы: