안드로이드 이미지 캐싱 후 어떻게 캐시

웹에서 이미지를 다운로드 한 후 어떻게 캐시 할 수 있습니까?



답변

그리고 펀치 라인 : 시스템 캐시를 사용하십시오.

URL url = new URL(strUrl);
URLConnection connection = url.openConnection();
connection.setUseCaches(true);
Object response = connection.getContent();
if (response instanceof Bitmap) {
  Bitmap bitmap = (Bitmap)response;
} 

브라우저와 공유되는 메모리 및 플래시 ROM 캐시를 모두 제공합니다.

grr. 누군가 나에게 캐시 관리자를 작성하기 전에 나에게 말했으면 좋겠다.


답변

connection.setUseCaches위 의 우아한 솔루션 과 관련하여 슬프게도 추가 노력 없이는 작동하지 않습니다. ResponseCacheusing 을 설치해야합니다 ResponseCache.setDefault. 그렇지 않으면 비트 HttpURLConnection를 자동으로 무시합니다 setUseCaches(true).

자세한 내용은 상단의 주석을 참조 FileResponseCache.java하십시오.

http://libs-for-android.googlecode.com/svn/reference/com/google/android/filecache/FileResponseCache.html

(나는 이것을 의견에 게시 할 것이지만 분명히 충분한 업장이 없습니다.)


답변

비트 맵으로 변환 한 다음 Collection (HashMap, List 등)에 저장하거나 SDcard에 쓸 수 있습니다.

첫 번째 방법을 사용하여 애플리케이션 공간에 저장하는 경우, 숫자가 큰 경우 (위기 동안 가비지 수집 됨) 구체적 으로 java.lang.ref.SoftReference 주위를 랩핑 할 수 있습니다 . 그래도 재로드가 발생할 수 있습니다.

HashMap<String,SoftReference<Bitmap>> imageCache =
        new HashMap<String,SoftReference<Bitmap>>();

SDcard에 작성하면 다시로드 할 필요가 없습니다. 단지 사용자 권한.


답변

LruCache이미지를 효율적으로 캐시하는 데 사용 합니다. Android 개발자 사이트LruCache 에서 읽을 수 있습니다

안드로이드에서 이미지 다운로드 및 캐싱을 위해 아래 솔루션을 사용했습니다. 아래 단계를 수행 할 수 있습니다.

1 단계 :
클래스 이름 지정 ImagesCache. 나는 사용했다Singleton object for this class

import android.graphics.Bitmap;
import android.support.v4.util.LruCache;

public class ImagesCache
{
    private  LruCache<String, Bitmap> imagesWarehouse;

    private static ImagesCache cache;

    public static ImagesCache getInstance()
    {
        if(cache == null)
        {
            cache = new ImagesCache();
        }

        return cache;
    }

    public void initializeCache()
    {
        final int maxMemory = (int) (Runtime.getRuntime().maxMemory() /1024);

        final int cacheSize = maxMemory / 8;

        System.out.println("cache size = "+cacheSize);

        imagesWarehouse = new LruCache<String, Bitmap>(cacheSize)
                {
                    protected int sizeOf(String key, Bitmap value)
                    {
                        // The cache size will be measured in kilobytes rather than number of items.

                        int bitmapByteCount = value.getRowBytes() * value.getHeight();

                        return bitmapByteCount / 1024;
                    }
                };
    }

    public void addImageToWarehouse(String key, Bitmap value)
    {
        if(imagesWarehouse != null && imagesWarehouse.get(key) == null)
        {
            imagesWarehouse.put(key, value);
        }
    }

    public Bitmap getImageFromWarehouse(String key)
    {
        if(key != null)
        {
            return imagesWarehouse.get(key);
        }
        else
        {
            return null;
        }
    }

    public void removeImageFromWarehouse(String key)
    {
        imagesWarehouse.remove(key);
    }

    public void clearCache()
    {
        if(imagesWarehouse != null)
        {
            imagesWarehouse.evictAll();
        }
    }

}

2 단계:

캐시에서 비트 맵을 사용할 수없는 경우 사용되는 DownloadImageTask라는 다른 클래스를 여기에서 다운로드하십시오.

public class DownloadImageTask extends AsyncTask<String, Void, Bitmap>
{
    private int inSampleSize = 0;

    private String imageUrl;

    private BaseAdapter adapter;

    private ImagesCache cache;

    private int desiredWidth, desiredHeight;

    private Bitmap image = null;

    private ImageView ivImageView;

    public DownloadImageTask(BaseAdapter adapter, int desiredWidth, int desiredHeight)
    {
        this.adapter = adapter;

        this.cache = ImagesCache.getInstance();

        this.desiredWidth = desiredWidth;

        this.desiredHeight = desiredHeight;
    }

    public DownloadImageTask(ImagesCache cache, ImageView ivImageView, int desireWidth, int desireHeight)
    {
        this.cache = cache;

        this.ivImageView = ivImageView;

        this.desiredHeight = desireHeight;

        this.desiredWidth = desireWidth;
    }

    @Override
    protected Bitmap doInBackground(String... params)
    {
        imageUrl = params[0];

        return getImage(imageUrl);
    }

    @Override
    protected void onPostExecute(Bitmap result)
    {
        super.onPostExecute(result);

        if(result != null)
        {
            cache.addImageToWarehouse(imageUrl, result);

            if(ivImageView != null)
            {
                ivImageView.setImageBitmap(result);
            }
            else if(adapter != null)
            {
                adapter.notifyDataSetChanged();
            }
        }
    }

    private Bitmap getImage(String imageUrl)
    {
        if(cache.getImageFromWarehouse(imageUrl) == null)
        {
            BitmapFactory.Options options = new BitmapFactory.Options();

            options.inJustDecodeBounds = true;

            options.inSampleSize = inSampleSize;

            try
            {
                URL url = new URL(imageUrl);

                HttpURLConnection connection = (HttpURLConnection)url.openConnection();

                InputStream stream = connection.getInputStream();

                image = BitmapFactory.decodeStream(stream, null, options);

                int imageWidth = options.outWidth;

                int imageHeight = options.outHeight;

                if(imageWidth > desiredWidth || imageHeight > desiredHeight)
                {
                    System.out.println("imageWidth:"+imageWidth+", imageHeight:"+imageHeight);

                    inSampleSize = inSampleSize + 2;

                    getImage(imageUrl);
                }
                else
                {
                    options.inJustDecodeBounds = false;

                    connection = (HttpURLConnection)url.openConnection();

                    stream = connection.getInputStream();

                    image = BitmapFactory.decodeStream(stream, null, options);

                    return image;
                }
            }

            catch(Exception e)
            {
                Log.e("getImage", e.toString());
            }
        }

        return image;
    }

3 단계 : 에서 사용하여 Activity또는Adapter

참고 :Activity 클래스의 URL에서 이미지를로드하려는 경우 . 의 두 번째 생성자를 사용 DownloadImageTask하지만 Adapter첫 번째 생성자 를 사용하여 이미지를 표시 하려면 DownloadImageTask(예를 들어 이미지가 ListView있고 ‘어댑터’에서 이미지를 설정하는 중)

활동에서 사용 :

ImageView imv = (ImageView) findViewById(R.id.imageView);
ImagesCache cache = ImagesCache.getInstance();//Singleton instance handled in ImagesCache class.
cache.initializeCache();

String img = "your_image_url_here";

Bitmap bm = cache.getImageFromWarehouse(img);

if(bm != null)
{
  imv.setImageBitmap(bm);
}
else
{
  imv.setImageBitmap(null);

  DownloadImageTask imgTask = new DownloadImageTask(cache, imv, 300, 300);//Since you are using it from `Activity` call second Constructor.

  imgTask.execute(img);
}

어댑터 사용 :

ImageView imv = (ImageView) rowView.findViewById(R.id.imageView);
ImagesCache cache = ImagesCache.getInstance();
cache.initializeCache();

String img = "your_image_url_here";

Bitmap bm = cache.getImageFromWarehouse(img);

if(bm != null)
{
  imv.setImageBitmap(bm);
}
else
{
  imv.setImageBitmap(null);

  DownloadImageTask imgTask = new DownloadImageTask(this, 300, 300);//Since you are using it from `Adapter` call first Constructor.

  imgTask.execute(img);
}

노트 :

cache.initializeCache()이 문장을 응용 프로그램의 첫 번째 활동에서 사용할 수 있습니다. 캐시를 초기화하면 ImagesCache인스턴스를 사용하는 경우 매번 캐시를 초기화 할 필요가 없습니다 .

나는 설명을 잘하지 않지만 초보자가 캐시를 사용하는 방법 LruCache과 사용법에 도움이되기를 바랍니다. 🙂

편집하다:

이제 일이라고 아주 유명한 라이브러리가 PicassoGlide안드로이드 응용 프로그램에서 매우 효율적으로 부하 이미지를 사용할 수 있습니다. 이 매우 간단하고 유용한 라이브러리 시도 안드로이드 피카소글라이드를 들어 안드로이드 . 캐시 이미지에 대해 걱정할 필요가 없습니다.

Picasso는 응용 프로그램에서 번거롭지 않은 이미지 로딩을 허용합니다. 종종 한 줄의 코드로도 가능합니다!

피카소와 마찬가지로 글라이드는 여러 소스에서 이미지를로드하고 표시 할 수 있으며 이미지 조작시 캐싱을 관리하고 메모리에 미치는 영향을 줄입니다. 공식 Google 앱 (Google I / O 2015 용 앱 등)에서 사용되었으며 Picasso만큼 인기가 있습니다. 이 시리즈에서는 피카소보다 글라이드의 차이점과 장점을 살펴 보겠습니다.

글라이드와 피카소의 차이점에 대한 블로그를 방문 할 수도 있습니다


답변

이미지를 다운로드하여 메모리 카드에 저장하려면 다음과 같이하십시오.

//First create a new URL object 
URL url = new URL("http://www.google.co.uk/logos/holiday09_2.gif")

//Next create a file, the example below will save to the SDCARD using JPEG format
File file = new File("/sdcard/example.jpg");

//Next create a Bitmap object and download the image to bitmap
Bitmap bitmap = BitmapFactory.decodeStream(url.openStream());

//Finally compress the bitmap, saving to the file previously created
bitmap.compress(CompressFormat.JPEG, 100, new FileOutputStream(file));

매니페스트에 인터넷 권한을 추가하는 것을 잊지 마십시오.

<uses-permission android:name="android.permission.INTERNET" />


답변

droidfu의 이미지 캐시 사용을 고려할 것입니다. 인 메모리 및 디스크 기반 이미지 캐시를 모두 구현합니다. ImageCache 라이브러리를 활용하는 WebImageView도 얻을 수 있습니다.

다음은 droidfu 및 WebImageView에 대한 전체 설명입니다.
http://brainflush.wordpress.com/2009/11/23/droid-fu-part-2-webimageview-and-webgalleryadapter/


답변

SoftReferences를 사용해 보았습니다 .Android에서 너무 적극적으로 사용하여 사용하지 않아도됩니다.