Skip to content

Files

Latest commit

40f4477 ยท Aug 30, 2018

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