Skip to content

Latest commit

ย 

History

History
356 lines (238 loc) ยท 11.9 KB

android Image Caching.md

File metadata and controls

356 lines (238 loc) ยท 11.9 KB

android Image Caching

Android Image Caching ๋Œ€ํ•˜์—ฌ

Present Time: 2018-06-09-Fri

Last Updated: 2018-06-14-Thur


0. ๊ณต์‹ ๋ฌธ์„œ

0-1. ๊ฐ€์ด๋“œ

1.์บ์‹ฑ์ด๋ž€?

๋ฐ์ดํ„ฐ์— ๋Œ€ํ•œ ํ–ฅํ›„ ์š”์ฒญ์— ์‹ ์†ํ•˜๊ฒŒ ๋Œ€์‘ ํ•  ์ˆ˜ ์žˆ๋„๋ก ๋ฐ์ดํ„ฐ๋ฅผ ๋กœ์ปฌ์— ์ €์žฅํ•˜๋Š” ํ”„๋กœ์„ธ์Šค

๋น„ํŠธ๋งต ์บ์‹œ

์ด๋ฏธ์ง€๋ฅผ ๋น„ํŠธ๋งต์œผ๋กœ ๋ฐ”๊พธ์–ด ๋ฉ”๋ชจ๋ฆฌ์— ์ €์žฅํ•˜๋Š” ๊ฒƒ์ด๋‹ค.

๋ฉ”๋ชจ๋ฆฌ ์บ์‹œ

๋ฉ”๋ชจ๋ฆฌ ์บ์‹œ๋Š” ์›๋ณธ์˜ ์••์ถ•๋œ ํ˜•์‹์œผ๋กœ ์ €์žฅ๋œ๋‹ค. ์ด๋ฏธ์ง€๋Š” ํ™”๋ฉด์— ํ‘œ์‹œ๋˜๊ธฐ ์ „์— ์ด ์บ์‹œ์—์„œ ๋””์ฝ”๋“œ ๋˜์–ด ๊ฐ€์ ธ์˜จ๋‹ค

์ด ์บ์‹œ๋Š” ์•ฑ์ด ๋ฐฑ๊ทธ๋ผ์šด๋“œ๋กœ ๊ฐ€๋ฉด ์ง€์›Œ์ง„๋‹ค.

๋””์Šคํฌ ์บ์‹œ

๋””์Šคํฌ ์บ์‹œ๋Š” ๋ฐ์ดํ„ฐ๊ฐ€ ์ง€์†์ ์œผ๋กœ ๋‚จ์•„์žˆ๊ณ  ์šฉ๋Ÿ‰๋„ ๋ฉ”๋ชจ๋ฆฌ ์บ์‹œ ๋ณด๋‹ค ๋” ๋งŽ์ด ์“ธ ์ˆ˜ ์žˆ๋‹ค.ํ•˜์ง€๋งŒ ๋ฉ”๋ชจ๋ฆฌ ์บ์‹œ๋ณด๋‹ค ๋Š๋ฆฌ๋‹ค.

์ด ์บ์‹œ๋Š” ์•ฑ์ด ๋ฐฑ๊ทธ๋ผ์šด๋“œ ์ƒํƒœ๊ฑฐ๋‚˜, ์ข…๋ฃŒ,์žฅ์น˜๊ฐ€ ๊บผ์ ธ ์žˆ์„ ๋•Œ ์—†์–ด์ง€์ง€ ์•Š๋Š”๋‹ค. ์‚ฌ์šฉ์ž๋Š” ์•ˆ๋“œ๋กœ์ด๋“œ ์„ค์ •๋ฉ”๋‰ด์—์„œ ๋””์Šคํฌ ์บ์‹œ๋ฅผ ์—†์•จ ์ˆ˜ ์žˆ๋‹ค.

2.Image Caching์„ ํ•˜๋Š” ์ด์œ 

  • ํŠน์ • URL ์ด๋ฏธ์ง€๋ฅผ ๋ฆฌ์ŠคํŠธ๋กœ ๋ณด์—ฌ์ค„ ๋•Œ, ๋™์ผ ํ•œ URL ์ด๋ฏธ์ง€๋ฅผ ๋งค๋ฒˆ ๋‹ค์šด ๋ฐ›์•„ ์ถœ๋ ฅํ•˜๋ฉด ๋น„ํšจ์œจ
  • ์‚ฌ์šฉ์ž ์‘๋‹ต์†๋„ ๋Š๋ ค์ง

###3.์ฝ”๋“œ

๋น„ํŠธ๋งต ์บ์‹œ ์ฝ”๋“œ

private LruCache<String, Bitmap> mMemoryCache;

@Override
protected void onCreate(Bundle savedInstanceState) {
    ...
    // Get max available VM memory, exceeding this amount will throw an
    // OutOfMemory exception. Stored in kilobytes as LruCache takes an
    // int in its constructor.
    //๋ฉ”๋ชจ๋ฆฌ ์‚ฌ์šฉ๋Ÿ‰ ์•Œ๊ธฐ์œ„ํ•ด์„œ
    final int maxMemory = (int) (Runtime.getRuntime().maxMemory() / 1024);

    // Use 1/8th of the available memory for this memory cache.
    final int cacheSize = maxMemory / 8;

    mMemoryCache = new LruCache<String, Bitmap>(cacheSize) {
        @Override
        protected int sizeOf(String key, Bitmap bitmap) {
            // The cache size will be measured in kilobytes rather than
            // number of items.
            return bitmap.getByteCount() / 1024;
        }
    };
    ...
}

public void addBitmapToMemoryCache(String key, Bitmap bitmap) {
    if (getBitmapFromMemCache(key) == null) {
        mMemoryCache.put(key, bitmap);//๋ฉ”๋ชจ๋ฆฌ ์บ์‹œ์— ์ €์žฅ
    }
}
//์บ์‰ฌ๋œ ์ด๋ฏธ์ง€ ๊ฐ€์ ธ์˜ค๊ธฐ
public Bitmap getBitmapFromMemCache(String key) {
    return mMemoryCache.get(key);
}
LruCache ์‚ฌ์šฉ์‹œ maxSize ๋ฐ sizeOf()์‚ฌ์šฉ ์˜๋ฏธ

-LruCache๋ฅผ ์ƒ์„ฑํ•  ๋•Œ ์ •ํ•ด์ฃผ๋Š” maxSize๋Š” ์ด๋ฏธ์ง€ ๊ฐฏ์ˆ˜๋„ ๋  ์ˆ˜ ์žˆ๊ณ  ๊ฐ€์šฉ ๋ฉ”๋ชจ๋ฆฌ๋„ ๋  ์ˆ˜ ์žˆ๋‹ค.

  • sizeOf()๋ฉ”์†Œ๋“œ๋ฅผ Override ํ•˜์ง€ ์•Š์€ ๊ฒฝ์šฐ

    int maxSize = 10;
    
    LruCache<String, Bitmap> cache = new LruCache<String, Bitmap>(maxSize);
    

    ์ด๋ ‡๊ฒŒ ๊ตฌํ˜„ํ•˜๋ฉด ์บ์‹œ์— ์ €์žฅ๋œ๋Š ์ด๋ฏธ์ง€ ๊ฐฏ์ˆ˜๊ฐ€ 10๊ฐœ๋ผ๋Š” ๋œป์ด๋‹ค.

  • sizeOf()๋ฉ”์†Œ๋“œ๋ฅผ Override ํ–ˆ์„ ๊ฒฝ์šฐ

    int memoryClass = ((ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE)).getMemoryClass();
    int maxSize = 1024 * 1024 * memoryClass / 4;
    
    LruCache<String, Bitmap> cache = new LruCache<String, Bitmap>(maxSize){
    
        @Override
    
        protected int sizeOf(String key, Bitmap bitmap){
    
        	return bitmap.getByteCount();
    
       }
    
    };
    

    ์ด๋ ‡๊ฒŒ ๊ตฌํ˜„ํ•˜๋ฉด ์บ์‹œ์˜ ๊ฐ€์šฉ ๋ฉ”๋ชจ๋ฆฌ๊ฐ€ ์–ดํ”Œ๋ฆฌ์ผ€์ด์…˜์ด ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š” ๋ฉ”๋ชจ๋ฆฌ์˜ 1/4๋งŒํผ ์บ์‹œ์— ์“ธ ์ˆ˜ ์žˆ๊ฒŒ ํ•˜๊ฒ ๋‹ค๋ผ๋Š” ์˜๋ฏธ์ด๋‹ค.

๋””์Šคํฌ์บ์‹ฑ

private DiskLruCache mDiskLruCache;
private final Object mDiskCacheLock = new Object();
private boolean mDiskCacheStarting = true;
private static final int DISK_CACHE_SIZE = 1024 * 1024 * 10; // 10MB
private static final String DISK_CACHE_SUBDIR = "thumbnails";

@Override
protected void onCreate(Bundle savedInstanceState) {
    ...
    // Initialize memory cache
    ...
    // Initialize disk cache on background thread
    //๋ฐฑ๊ทธ๋ผ์šด๋“œ์— ๋””์Šคํฌ ์บ์‹œ ์ดˆ๊ธฐํ™”
    File cacheDir = getDiskCacheDir(this, DISK_CACHE_SUBDIR);
    new InitDiskCacheTask().execute(cacheDir);
    ...
}
//๋น„๋™๊ธฐ๋กœ ๋ฐฑ๊ทธ๋ผ์šด๋“œ์—์„œ ๋””์Šคํฌ ์บ์‹œ๋ฅผ ์‹คํ–‰ํ•œ๋‹ค.
class InitDiskCacheTask extends AsyncTask<File, Void, Void> {
    @Override
    protected Void doInBackground(File... params) {
        synchronized (mDiskCacheLock) {
            File cacheDir = params[0];//๋””์Šคํฌ ์บ์‹œ๊ฐ€ ์ €์žฅ๋œ ๋””๋ ‰ํ† ๋ฆฌ
            mDiskLruCache = DiskLruCache.open(cacheDir, DISK_CACHE_SIZE);
            mDiskCacheStarting = false; //์ดˆ๊ธฐํ™” ์™„๋ฃŒ
            mDiskCacheLock.notifyAll(); //์ž‘์—…์œผ๋กœ ์—ฐ๊ฒฐ๋œ ์“ฐ๋ ˆ๋“œ์—๊ฒŒ ์•Œ๋ฆฐ๋‹ค.
        }
        return null;
    }
}

class BitmapWorkerTask extends AsyncTask<Integer, Void, Bitmap> {
    ...
    // Decode image in background.
    @Override
    protected Bitmap doInBackground(Integer... params) {
    
        final String imageKey = String.valueOf(params[0]);

        // Check disk cache in background thread
        ๋ฐฑ๊ทธ๋ผ์šด๋“œ ์Šค๋ ˆ๋“œ์—์„œ ํ•„์š”ํ•œ ๋น„ํŠธ๋งต์„ ๊ฐ€์ ธ์˜จ๋‹ค.
        Bitmap bitmap = getBitmapFromDiskCache(imageKey);

        if (bitmap == null) { // Not found in disk cache
            // Process as normal
            //์ผ๋ฐ˜์ ์œผ๋กœ ๋””์ฝ”๋”ฉํ•˜๋Š” ๋ฐฉ๋ฒ•
            final Bitmap bitmap = decodeSampledBitmapFromResource(
                    getResources(), params[0], 100, 100));
        }

		//๋””์ฝ”๋”ฉ๋œ ๋น„ํŠธ๋งต์€ ํ•ด๋‹น ํ‚ค์™€ ํ•จ๊ป˜ ์บ์‹œ ์ฒ˜๋ฆฌ ๋œ๋‹ค.
        addBitmapToCache(imageKey, bitmap);

        return bitmap;
    }
    ...
}

public void addBitmapToCache(String key, Bitmap bitmap) {
    // Add to memory cache as before
    ๋ฉ”๋ชจ๋ฆฌ์บ์‹œ์— ์ €์žฅํ•œ๋‹ค
    if (getBitmapFromMemCache(key) == null) {
        mMemoryCache.put(key, bitmap);
    }

    // Also add to disk cache
    //๋””์Šคํฌ ์บ์‹œ์—๋„ ์ €์žฅํ•œ๋‹ค.
    synchronized (mDiskCacheLock) {//๋ฐฑ๊ทธ๋ผ์šด๋“œ์—์„œ ๋””์Šคํฌ ์บ์‹œ๊ฐ€ ์‹œํ–‰๋˜์—ˆ์„ ๋•Œ๋ฅผ ๊ธฐ๋‹ค๋ฆฐ๋‹ค
    
        if (mDiskLruCache != null && mDiskLruCache.get(key) == null) {
            mDiskLruCache.put(key, bitmap);
        }
    }
}

public Bitmap getBitmapFromDiskCache(String key) {
    synchronized (mDiskCacheLock) {
        // Wait while disk cache is started from background thread
        //๋ฐฑ๊ทธ๋ผ์šด๋“œ์—์„œ ๋””์Šคํฌ ์บ์‹œ๊ฐ€ ์‹œํ–‰๋˜๊ธธ ๊ธฐ๋‹ค๋ฆฐ๋‹ค.
        while (mDiskCacheStarting) {
            try {
                mDiskCacheLock.wait();
            } catch (InterruptedException e) {}
        }
        if (mDiskLruCache != null) {
            return mDiskLruCache.get(key);
        }
    }
    return null;
}


public static File getDiskCacheDir(Context context, String uniqueName) {
       // ์‚ฌ์šฉ์„ ํ•ด๋ณด๊ณ  ์™ธ๋ถ€์ €์žฅ์†Œ์˜ ์บ์‹œ๊ฐ€ ์ž‘๋™ํ•˜์ง€ ์•Š๋Š”๋‹ค๋ฉด ๋‚ด๋ถ€ ์ €์žฅ์†Œ๋ฅผ ์‚ฌ์šฉํ•˜๋ผ๋Š” ๋‚ด์šฉ์ด์˜ ์ฝ”๋“œ์ธ๋ฐ ์ž˜ ์ดํ•ด๊ฐ€ ์•ˆ๋˜์šฉใ…‡

    final String cachePath =          Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState()) ||
                    !isExternalStorageRemovable() ? getExternalCacheDir(context).getPath() :
                            context.getCacheDir().getPath();

    return new File(cachePath + File.separator + uniqueName);
}

AsyncTask<Params, Progress,Result>

Params-ํŒŒ๋ผ๋ฏธํ„ฐ ํƒ€์ž…์€ ์ž‘์—… ์‹คํ–‰ ์‹œ์— ์†ก์‹ 

Progress-dolnBackground* ์ž‘์—… ์‹œ ์ง„ํ–‰ ๋‹จ์œ„์˜ ํƒ€์ž…

Result-dolnBackground ๋ฆฌํ„ด๊ฐ’

์šฉ์–ด์ •๋ฆฌ

๊ฐ€์šฉ๋ฉ”๋ชจ๋ฆฌ: ์‹ค์ œ ๋ฉ”๋ชจ๋ฆฌ ์‚ฌ์šฉ๊ฐ€๋Šฅ ์—ฌ์œ 

AsyncTask: ์Šค๋ ˆ๋“œ ๊ฐ„์˜ ๋™๊ธฐํ™”๋ฅผ ๊ณ ๋ คํ•ด์„œ ์†Œํ”„ํŠธ์›จ์–ด๋ฅผ ์„ค๊ณ„ํ–์•„ํ•˜๊ณ  ํ•ธ๋“ค๋Ÿฌ ์‚ฌ์šฉ์œผ๋กœ ๋ณต์žกํ•˜๊ณ  ๋ฒˆ๊ฑฐ๋กœ์šด ์ž‘์—…์„ ์ข€ ๋” ์‰ฝ๊ฒŒ ๋งŒ๋“ค์–ด์ฃผ๋Š” ์ถ”์ƒํด๋ž˜์Šค์ด๋‹ค.

donlnBackground: ๊ธฐ์กด์˜ Thread์—์„œ์˜ run() ๋ฉ”์†Œ๋“œ๋ผ๊ณ  ์ƒ๊ฐํ•˜๋ฉด ๋œ๋‹ค.

synchronized: ๋™๊ธฐํ™”. ๋‘˜ ์ด์ƒ์˜ ์“ฐ๋ ˆ๋“œ๊ฐ€ ํŒŒ์ผ์ด๋‚˜ ๋ฉ”๋ชจ๋ฆฌ๋ฅผ ๊ณต์œ ํ•˜๋Š” ๊ฒฝ์šฐ, ์ˆœ์„œ๋ฅผ ์ž˜ ๋งž์ถ”์–ด ๋‹ค๋ฅธ ์“ฐ๋ ˆ๋“œ๊ฐ€ ์ž์›์„ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ๋Š” ๋™์•ˆ ํ•œ ์“ฐ๋ ˆ๋“œ๊ฐ€ ์ ˆ๋Œ€ ์ž์›๋ฅผ ๋ณ€๊ฒฝํ•  ์ˆ˜ ์—†๋„๋ก ํ•ด์•ผํ•œ๋‹ค . ์ด๋Ÿฐ ์ƒํ™ฉ์„ ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ๋Š” ๋ฐฉ๋ฒ• ์ด๋‹ค.

โ€‹

4.Image Caching ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ

์—ฌ๋Ÿฌ ์˜คํ”ˆ ์†Œ์Šค ์ด๋ฏธ์ง€ ๋กœ๋”ฉ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋“ค์€ ์บ์‹œ,๋™์‹œ ์‹คํ–‰,์ทจ์†Œ ๋“ฑ์„ ๊ฐ„ํŽธํ•˜๊ฒŒ ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ๋„๋ก ๋„์™€์ค€๋‹ค.

Android Universal Image Loader

AUIL๋Š” ํ™”๋ฉด ํฌ๊ธฐ๋ฅผ ๊ธฐ์ค€์œผ๋กœ ์บ์‹œ์šฉ๋Ÿ‰์„ ์ œํ•œํ•˜๋Š” ๋“ฑ ๋‹ค์–‘ํ•œ ์บ์‹œ ์ •์ฑ…์„ ์ง€์›ํ•œ๋‹ค.

ImageLoader ๊ฐ์ฒด๋ฅผ ์ดˆ๊ธฐํ™”ํ•œ ํ›„์—, ๊ฐ์ข… ์˜ต์…˜์„ ์„ค์ •ํ•˜๊ณ  ์‚ฌ์šฉ ํ•  ์ˆ˜ ์žˆ๋‹ค.

DisplayImageOptions options = new DisplayImageOptions.Builder()  
                              .cacheInMemory()
                              .cacheOnDisc()
                              ...
                              .build();
ImageLoader.getInstance().displayImage(imageUrl, imageView, options);

*extend Application ํ•œ ํด๋ž˜์Šค๋งŒ ์‚ฌ์šฉ ๊ฐ€๋Šฅ

AQuery

AQuery๋Š” xmlํŒŒ์‹ฑ๊ณผ ๊ถŒํ•œ ๊ด€๋ฆฌ ๋“ฑ ๋‹ค์–‘ํ•œ ๊ธฐ๋Šฅ์„ ๊ฐ€์ง„ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฆฌ๋‚˜ ์ด๋ฏธ์ง€ ๋กœ๋”ฉ๊ณผ ์บ์‹œ๋ฅผ ์ œ๊ณตํ•œ๋‹ค.

AQuery aq = new AQuery(context);  
...
String imageUrl ="http://image.naver.com/goldrush.jpg";  
aq.id(R.id.imageView).image(imageUrl, true, true, 200,0);  

Libs for Android Image Loader

getSystem.Service()๋ฉ”์†Œ๋“œ๋ฅผ ์˜ค๋ฒ„๋ผ์ด๋“œํ•˜์—ฌ System ์„œ๋น„์Šค๋กœ ImageLoader ๊ฐ์ฒด๋ฅผ ์ฐธ์กฐ ํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•ด์•ผ ํ•œ๋‹ค. ๊ทธ๋Ÿฐ ๋‹ค์Œ ImageLoader.get() ๋ฉ”์„œ๋“œ๋ฅผ ํ˜ธ์ถœํ•ด์„œ ์ด๋ฏธ์ง€ ๋กœ๋”ฉํ•ด์•ผ ํ•œ๋‹ค

Callback callback = new Callback() {  
    public void onImageLoaded(ImageView view, String url) { ... }
    public void onImageError(ImageView view, String url, Throwable error) { ... }
};
ImageLoader.get(this).bind(view, imageUrl, callback);

*extend Application ํ•œ ํด๋ž˜์Šค๋งŒ ์‚ฌ์šฉ ๊ฐ€๋Šฅ

Volley Image Loader

๋„คํŠธ์›Œํฌ ํ†ต์‹ ๊ณผ ์บ์‹œ, ๋””์ฝ”๋”ฉ ๋“ฑ์„ ์•Œ์•„์„œ ํ•ด์ฃผ๋Š” networkImageView ๋ผ๋Š”ImageView๋ฅผ ์‚ฌ์šฉํ•œ ํด๋ž˜์Šค๋„ ์ œ๊ณตํ•œ๋‹ค. ๊ธฐ๋ณธ ์‚ฌ์šฉ๋ฒ•์€ requestQueue์— ์š”์ฒญ์„ ์ถ”๊ฐ€ํ•˜๊ณ , ๊ฒฐ๊ณผ๋ฅผ ์ฒ˜๋ฆฌํ•  ๋•Œ ์ฝœ๋ฐฑ ๊ฐœ์ฒด๋ฅผ ๋„˜๊ธด๋‹ค.

imageLoader = new ImageLoader(Volley.newRequestQueue(this),new LruBitmapCache());  
imageLoader.get(imageUrl,  
                imageLoader.getImageListener(
                    imageView, R.drawable.defaultIcon, R.drawable.errorIcon
                )
);

*SDK๋งค๋‹ˆ์ €๋ฅผ ํ†ตํ•œ ๋‹ค์šด๋กœ๋“œ ์ œ๊ณต x

git์—์„œ ๋ณต์‚ฌํ•ด์„œ ์‚ฌ์šฉํ•ด์•ผํ•จ

Picasso

ํ…Œ์ŠคํŠธ์™€ ๋””๋ฒ„๊ทธ์— ์œ ์šฉํ•ด์„œ ๊ฐœ๋ฐœ ํŽธ์˜์„ฑ์„ ๋งŽ์ด ๋ฐฐ๋ ค ํ–ˆ๋‹ค.

Picasso.with(context).load(imageUrl).resize(30, 30).into(imageView);  

####๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ณ„ ๋น„๊ต

์ดํ‰

AUIL๋Š” ๋‹ค๋ฅธ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์— ๋น„ํ•ด ๊ฑฐ์˜ ๋ชจ๋“  ๋ฉด์—์„œ ์••๋„์ ์ด๋‹ค. ๊ธฐ์กด ์ด๋ฏธ์ง€ ๋กœ๋”ฉ ๋ฌธ์ œ์˜ ๋Œ€๋ถ€๋ถ„์„ ์ž˜ ํ•ด๊ฒฐํ•˜๊ณ  ์žˆ๊ณ , ์—ฌ๋Ÿฌ ์ข…๋ฅ˜์˜ ์บ์‹œ๋‚˜ ๋‹ค์šด๋กœ๋”, ๋””์ฝ”๋” ๋“ฑ์ด ์ด๋ฏธ ๊ตฌํ˜„๋˜์–ด ์žˆ์–ด ์‚ฌ์šฉ์ž๊ฐ€ ์ฑ„์›Œ์ค˜์•ผ ํ•  ๋ถ€๋ถ„์ด ๋ณ„๋กœ ์—†๋‹ค.

AQuery๋Š” ์ง๊ด€์ ์ธ ์‚ฌ์šฉ์ด ์–ด๋ ต๋‹ค. ๋ฉ”๋ชจ๋ฆฌ ์บ์‹œ์˜ ํฌ๊ธฐ ์ œํ•œ์„ ์ ˆ์ •ํ•  ๋•Œ ๋ฉ”์†Œ๋“œ ํ˜ธ์ถœ์ด ์ด๋ฆฌ์†กํ•œ ์ ์ด ์กด์žฌํ•œ๋‹ค.

Libs for Androidsms deprecate๋œ ํ”„๋กœ์ ํŠธ์ธ๋งŒํ‹ˆ ์‚ฌ์šฉํ•˜์ง€ ์•Š๋Š” ํŽธ์ด ์ข‹๋‹ค.

droid4me ๋‹ค๋ฅธ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ณด๋‹ค ๊ธฐ๋ณธ ๊ตฌํ˜„ ์ˆ˜์ค€์ด ๋ถ€์กฑํ•˜์—ฌ ๋””์Šคํฌ ์บ์‹œ๋‚˜ ๋””์ฝ”๋”ฉ ๋ถ€๋ถ„์„ ์‚ฌ์šฉ์ž๊ฐ€ ์ง์ ‘ ๊ตฌํ˜„ํ•ด์•ผํ•œ๋‹ค.

Volley ImageLoader๋Š” ๋ฉ”๋ชจ๋ฆฌ ์บ์‹œ๋Š” ๊ตฌํ˜„์ฒด๋ฅผ ์ง์ ‘ ๋งŒ๋“ค์–ด์ค˜์•ผ ํ•˜๊ณ  ๋””์ฝ”๋”ฉ ๊ธฐ๋Šฅ ๋ฆฌ์‚ฌ์ด์ฆˆ ๋ฐ–์— ์ง€์›ํ•˜์ง€ ์•Š๋Š” ๋“ฑ ์‚ฌ์šฉ์„ฑ ์ธก๋ฉด์—์„œ ๋‹ค์†Œ ๋ถ€์กฑํ•˜๋‹ค.

Picasso๋Š” ๋‹ค๋ฅธ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ณด๋‹ค ๊ฐ„๋‹จํ•˜๋‹ค. ์ด๋ฏธ์ง€ ๋กœ๋”ฉ ๋ฌธ์ œ ํ•ด๊ฒฐ์— ํ•„์š”ํ•œ ๊ธฐ๋Šฅ๋“ค๋„ ์ถฉ๋ถ„ํ•˜๊ณ  ๋””๋ฒ„๊น…์„ ๋„์™€์ฃผ๋Š” ๊ธฐ๋Šฅ๋„ ๋…์ฐฝ์ ์ด๋‹ค.