Как эффективно загружать интернет-изображения в gridview? - PullRequest
7 голосов
/ 19 ноября 2010

Я использую следующий пример для отображения интернет-изображений в своей деятельности.

http://developer.android.com/resources/tutorials/views/hello-gridview.html

В адаптере пользовательских изображений я непосредственно загружаю изображения из Интернета и назначаю их для просмотра изображений.

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

Когда я прокручиваю gridview, он снова и снова загружает изображения, и поэтому просмотр сетки очень медленно

Есть ли кеширование или какая-нибудь полезная техника, чтобы сделать это быстрее?

Ответы [ 3 ]

13 голосов
/ 19 ноября 2010

Создайте глобальный и статический метод, который возвращает растровое изображение. Этот метод будет принимать параметры: context, imageUrl и imageName.

в методе:

  1. проверить, существует ли файл в кеше. если это так, верните растровое изображение

        if(new File(context.getCacheDir(), imageName).exists())
            return BitmapFactory.decodeFile(new File(context.getCacheDir(), imageName).getPath());
    
  2. в противном случае вы должны загрузить изображение из Интернета и сохранить его в кеше:

    image = BitmapFactory.decodeStream(HttpClient.fetchInputStream(imageUrl));
    
    
    <pre><code>FileOutputStream fos = null;
    try {
        fos = new FileOutputStream(new File(context.getCacheDir(), imageName));
    }
    
    
    //this should never happen
    catch(FileNotFoundException e) {
        if(Constants.LOGGING)
            Log.e(TAG, e.toString(), e);
    }
    
    
    //if the file couldn't be saved
    if(!image.compress(Bitmap.CompressFormat.JPEG, 100, fos)) {
        Log.e(TAG, "The image could not be saved: " + imageName + " - " + imageUrl);
        image = BitmapFactory.decodeResource(context.getResources(), R.drawable.default_cached_image);
    }
    fos.flush();
    fos.close();
    
    
    return image;
    

предварительно загружает Vector<SoftReference<Bitmap>> объект со всеми растровыми изображениями, используя описанный выше метод в классе AsyncTask, а также другой List, содержащий Map imageUrls и imageNames (для последующего доступа, когда вам необходимо перезагрузить изображение), затем установите адаптер GridView.

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

поэтому в вашем методе getView может быть что-то вроде (где icons - это Vector тип удержания SoftReference<Bitmap>:

myImageView.setImageBitmap(icons.get(position).get());

вам нужно будет сделать проверку:

if(icons.get(position).get() == null) {
    myImageView.setImageBitmap(defaultBitmap);
    new ReloadImageTask(context).execute(position);
}

в классе ReloadImageTask AsyncTask, просто вызовите глобальный метод, созданный сверху, с правильными параметрами, затем notifyDataSetChanged в onPostExecute

может потребоваться выполнить дополнительную работу, чтобы не запускать этот AsyncTask, когда он уже запущен для определенного элемента

0 голосов
/ 02 июля 2011

Вы можете попробовать DroidFu.Мое приложение использует ImageCache.Есть также какая-то разновидность просмотра изображений в Интернете или что-то в этом роде в библиотеке.В частности, смотрите WebImageView и WebGalleryAdapter: http://mttkay.github.com/droid-fu/index-all.html

Отредактировано, чтобы добавить: Проект droid-fu устарел в пользу Ignition.https://github.com/mttkay/ignition

0 голосов
/ 19 ноября 2010

Вам нужно будет реализовать кеширование самостоятельно. Создайте прокси-класс, который будет загружать изображения. В getView попросите этот класс загрузить изображение, передав URL-адрес. В прокси-классе создайте HashMap, который отобразит URL-адрес на растровое изображение. Если ключ для переданного URL не существует, загрузите изображение и сохраните его. В противном случае возвращается сохраненное растровое изображение, преобразованное в imageView.

Конечно, вы не можете позволить себе хранить столько изображений, сколько захотите. Вам необходимо установить ограничение, например, 10 изображений, исходя из ожидаемого размера изображения. Когда лимит превышен, вам нужно отказаться от старых изображений в пользу новых.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...