web-gelistirme-sc.com

Android lrucache kullanarak örnek

Android LruCache anlamak için yardıma ihtiyacım var. Yüklemeyi/kaydırmayı daha iyi hale getirmek için görüntüleri ızgara görünümüme yüklemek istiyorum. Birisi lütfen LruCache kullanarak bir örnek kod gönderebilir mi? Şimdiden teşekkürler.

36
MobDev

Aşağıda LruCache kullanmak için yaptığım bir sınıf var, bu, Daha Az Yaparak Daha İyi Yapma: Google I/O 2012 'de verilen İyi Bir Android Vatandaşı olmak.

TCImageLoader sınıfında neler yaptığım hakkında daha fazla bilgi için filme göz atın:

public class TCImageLoader implements ComponentCallbacks2 {
    private TCLruCache cache;

    public TCImageLoader(Context context) {
        ActivityManager am = (ActivityManager) context.getSystemService(
            Context.ACTIVITY_SERVICE);
        int maxKb = am.getMemoryClass() * 1024;
        int limitKb = maxKb / 8; // 1/8th of total ram
        cache = new TCLruCache(limitKb);
    }

    public void display(String url, ImageView imageview, int defaultresource) {
        imageview.setImageResource(defaultresource);
        Bitmap image = cache.get(url);
        if (image != null) {
            imageview.setImageBitmap(image);
        }
        else {
            new SetImageTask(imageview).execute(url);
        }
    }

    private class TCLruCache extends LruCache<String, Bitmap> {

        public TCLruCache(int maxSize) {
            super(maxSize);
        }

        @Override
        protected int sizeOf(ImagePoolKey key, Bitmap value) {
            int kbOfBitmap = value.getByteCount() / 1024;
            return kbOfBitmap;
        }
    }

    private class SetImageTask extends AsyncTask<String, Void, Integer> {
        private ImageView imageview;
        private Bitmap bmp;

        public SetImageTask(ImageView imageview) {
            this.imageview = imageview;
        }

        @Override
        protected Integer doInBackground(String... params) {
            String url = params[0];
            try {
                bmp = getBitmapFromURL(url);
                if (bmp != null) {
                    cache.put(url, bmp);
                }
                else {
                    return 0;
                }
            } catch (Exception e) {
                e.printStackTrace();
                return 0;
            }
            return 1;
        }

        @Override
        protected void onPostExecute(Integer result) {
            if (result == 1) {
                imageview.setImageBitmap(bmp);
            }
            super.onPostExecute(result);
        }

        private Bitmap getBitmapFromURL(String src) {
            try {
                URL url = new URL(src);
                HttpURLConnection connection
                    = (HttpURLConnection) url.openConnection();
                connection.setDoInput(true);
                connection.connect();
                InputStream input = connection.getInputStream();
                Bitmap myBitmap = BitmapFactory.decodeStream(input);
                return myBitmap;
            } catch (IOException e) {
                e.printStackTrace();
                return null;
            }
        }

    }

    @Override
    public void onConfigurationChanged(Configuration newConfig) {
    }

    @Override
    public void onLowMemory() {
    }

    @Override
    public void onTrimMemory(int level) {
        if (level >= TRIM_MEMORY_MODERATE) {
            cache.evictAll();
        }
        else if (level >= TRIM_MEMORY_BACKGROUND) {
            cache.trimToSize(cache.size() / 2);
        }
    }
}
38
ePeace

Benim için mükemmel bir şekilde çalışan gerçekten kolay bir yol buldum.

Bu Cache.Java sınıfıdır. Bu sınıfta, statik getInstance() yöntemi, tüm uygulamada sadece bir önbellek örneği oluşturmamızı sağlar. getLru() yöntemi, önbelleğe alınmış nesneyi almak için kullanılır, daha sonra nasıl kullanılacağı gösterilecektir. Bu önbellek geneldir, yani herhangi bir Nesne türünü içine kaydedebilirsiniz. Buradaki önbellek boyutu 1024'e ayarlanmıştır. Çok küçükse değiştirilebilir:

import Android.support.v4.util.LruCache;

public class Cache {

    private static Cache instance;
    private LruCache<Object, Object> lru;

    private Cache() {

        lru = new LruCache<Object, Object>(1024);

    }

    public static Cache getInstance() {

        if (instance == null) {

            instance = new Cache();
        }

        return instance;

    }

    public LruCache<Object, Object> getLru() {
        return lru;
    }
}

Bu, faaliyetinizdeki bitmap'i önbelleğe kaydettiğiniz koddur:

public void saveBitmapToCahche(){

        //The imageView that you want to save it's bitmap image resourse
        ImageView imageView = (ImageView) findViewById(R.id.imageViewID);

        //To get the bitmap from the imageView
        Bitmap bitmap = ((BitmapDrawable)imageview.getDrawable()).getBitmap();

        //Saving bitmap to cache. it will later be retrieved using the bitmap_image key
        Cache.getInstance().getLru().put("bitmap_image", bitmap);
    }

Bu, bitmap'i önbellekten aldığınız kod ve daha sonra bu görüntü bitmapine bir imageView ayarlayın:

public void retrieveBitmapFromCache(){

        //The imageView that you want to set to the retrieved bitmap
        ImageView imageView = (ImageView) findViewById(R.id.imageViewID);

        //To get bitmap from cache using the key. Must cast retrieved cache Object to Bitmap
        Bitmap bitmap = (Bitmap)Cache.getInstance().getLru().get("bitmap_image");

        //Setting imageView to retrieved bitmap from cache
        imageView.setImageBitmap(bitmap));

}

BU KADAR! Gördüğünüz gibi bu oldukça kolay ve basittir. 

  • ÖRNEK:

Uygulamamda, tüm görünümler sınıf değişkenlerine kaydedilir, böylece sınıftaki tüm yöntemlerle görülebilirler. İlk etkinliğimde, amacını kullanarak yeni bir etkinliğe başlamadan hemen önce, görüntü bitmapini onClickButton() yöntemiyle önbelleğe kaydederim. Ayrıca önbellekte bir dize değeri kaydedin:

public void onClickButton(View v){

    Bitmap bitmap = ((BitmapDrawable)imageView.getDrawable()).getBitmap();
    String name = textEdit.getText().toString();

    Cache.getInstance().getLru().put("bitmap_image", bitmap);
    Cache.getInstance().getLru().put("name", name);

    Intent i = new Intent(FirstActivity.this, SecondActivity.class);
    startActivity(i);
}

Sonra ikinci aktiviteden üçüncü bir aktiviteye de niyetlerini kullanarak gidiyorum. Son aktivitede diğer nesneleri önbelleğime kaydederim, sonra bir niyet kullanarak ilk aktiviteye geri dönerim. İlk aktiviteye geri döndüğümde, onCreate() yöntemi başlayacaktır. Bu yöntemde, önbelleğimin herhangi bir bitmap değerine veya herhangi bir String değerine (uygulama işime bağlı olarak) ayrı olup olmadığını kontrol ederim:

public ImageView imageView;
public EditText editText;

@Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_first);

        //...Other code...

        //The imageView that you want to save it's bitmap image resourse
        imageView = (ImageView) findViewById(R.id.imageViewID);

        //The editText that I want to save it's text into cache
        editText = (EditText)findViewById(R.id.editTextID);

        if(Cache.getInstance().getLru().get("name")!=null){
             editText.setText(Cache.getInstance().getLru().get("name").toString());
        }
        if(Cache.getInstance().getLru().get("bitmap_image")!=null){
             imageView.setImageBitmap((Bitmap)Cache.getInstance().getLru().get("bitmap_image"));
        }

        //...Other code...
    }
26
Crystal Engineer

Önbellek Bitmapleri 'nin LruCache ' in kullanımının gösterildiği yere göz atın.

Sayfadaki kodun ilgili kısmı aşağıdaki gibidir: -

private LruCache mMemoryCache;

@Override
protected void onCreate(Bundle savedInstanceState) {
    ...
    // Get memory class of this device, exceeding this amount will throw an
    // OutOfMemory exception.
    final int memClass = ((ActivityManager) context.getSystemService(
            Context.ACTIVITY_SERVICE)).getMemoryClass();

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

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

public void addBitmapToMemoryCache(String key, Bitmap bitmap) {
    if (getBitmapFromMemCache(key) == null) {
        mMemoryCache.put(key, bitmap);
    }
}

public Bitmap getBitmapFromMemCache(String key) {
    return mMemoryCache.get(key);
}
14
Rajesh

https://techienotes.info/2015/08/28/caching-bitmaps-in-Android-using-lrucache/

Bu link, görüntüleri LruCache kullanarak Gridview'e yüklemek için örnek bir uygulama içeren tam bir projeye sahiptir.

Bu sınıf LruCache kullanıyor ve linkte verilen koddan alınmış.

public class ImageAdapter extends BaseAdapter{
private String TAG = getClass().getSimpleName();
Context mContext;
ArrayList<Uri> imageList;

private LruCache<String, Bitmap> mLruCache;

public ImageAdapter (Context context){
    mContext = context;

    //Find out maximum memory available to application
    //1024 is used because LruCache constructor takes int in kilobytes
    final int maxMemory = (int) (Runtime.getRuntime().maxMemory() / 1024);

    // Use 1/4th of the available memory for this memory cache.
    final int cacheSize = maxMemory / 4;
    Log.d(TAG, "max memory " + maxMemory + " cache size " + cacheSize);

    // LruCache takes key-value pair in constructor
    // key is the string to refer bitmap
    // value is the stored bitmap
    mLruCache = new LruCache<String, Bitmap>(cacheSize) {
        @Override
        protected int sizeOf(String key, Bitmap bitmap) {
            // The cache size will be measured in kilobytes
            return bitmap.getByteCount() / 1024;
        }
    };

    imageList  = new ArrayList<Uri>();
    //Change this directory to where the images are stored
    String imagesFolderPath = Environment.getExternalStorageDirectory().getPath()+"/backups/";

    File imageSrcDir = new File (imagesFolderPath);
    // if directory not present, build it
    if (!imageSrcDir.exists()){
        imageSrcDir.mkdirs();
    }

    ArrayList<File> imagesInDir = getImagesFromDirectory(imageSrcDir);

    for (File file: imagesInDir){
        // imageList will hold Uri of all images
        imageList.add(Uri.fromFile(file));
    }
}

@Override
public int getCount() {
    return imageList.size();
}

@Override
public Object getItem(int position) {
    return null;
}

@Override
public long getItemId(int position) {
    return 0;
}

/**
 *
 * @param position The position of the item within the
 *                 adapter's data set of the item whose view we want.
 * @param convertView it is the view to be reused
 * @param parent The parent that this view will eventually be attached to
 * @return a View corresponding to the data at the specified position.
 */
@Override
public View getView(int position, View convertView, ViewGroup parent) {
    ImageView imageView;
    Bitmap thumbnailImage = null;
    if (convertView == null){
        imageView = new ImageView(mContext);
        imageView.setLayoutParams(
                //150,150 is size of imageview to display image
                new GridView.LayoutParams(150, 150));
        imageView.setScaleType(ImageView.ScaleType.CENTER_CROP);
    }
    else {
        imageView = (ImageView)convertView;
    }

    // Use the path as the key to LruCache
    final String imageKey = imageList.get(position).toString();

    //thumbnailImage is fetched from LRU cache
    thumbnailImage = getBitmapFromMemCache(imageKey);

    if (thumbnailImage == null){
        // if asked thumbnail is not present it will be put into cache
        BitmapWorkerTask task = new BitmapWorkerTask(imageView);
        task.execute(imageKey);
    }

    imageView.setImageBitmap(thumbnailImage);
    return imageView;
}

/**
 * This function returns the files from a directory
 * @param parentDirPath source directory in which images are located
 * @return list of Files
 */
private ArrayList<File> getImagesFromDirectory (File parentDirPath){
    ArrayList <File> listOfImages =  new ArrayList<File>();
    File [] fileArray = null;

    if ( parentDirPath.isDirectory() ){//parentDirPath.exists() &&
        //    &&
         //   parentDirPath.canRead()){
        fileArray = parentDirPath.listFiles();
    }

    if (fileArray == null){
        return listOfImages;    // return empty list
    }

    for (File file: fileArray){
        if (file.isDirectory()){
            listOfImages.addAll(getImagesFromDirectory(file));
        }
        else {
            // Only JPEG and PNG formats are included
            // for sake of simplicity
            if (file.getName().endsWith("png") ||
                    file.getName().endsWith("jpg")){
                listOfImages.add(file);
            }
        }
    }
    return listOfImages;
}

/**
 *  This function will return the scaled version of original image.
 *  Loading original images into thumbnail is wastage of computation
 *  and hence we will take put scaled version.
 */
private Bitmap getScaledImage (String imagePath){
    Bitmap bitmap = null;
    Uri imageUri = Uri.parse (imagePath);
    try{
        BitmapFactory.Options options = new BitmapFactory.Options();

        /**
         * inSampleSize flag if set to a value > 1,
         * requests the decoder to sub-sample the original image,
         * returning a smaller image to save memory.
         * This is a much faster operation as decoder just reads
         * every n-th pixel from given image, and thus
         * providing a smaller scaled image.
         * 'n' is the value set in inSampleSize
         * which would be a power of 2 which is downside
         * of this technique.
         */
        options.inSampleSize = 4;

        options.inScaled = true;

        InputStream inputStream = mContext.getContentResolver().openInputStream(imageUri);

        bitmap = BitmapFactory.decodeStream(inputStream, null, options);
    } catch (FileNotFoundException e) {
        e.printStackTrace();
    }

    return bitmap;
}

public void addBitmapToMemoryCache(String key, Bitmap bitmap) {
    if (getBitmapFromMemCache(key) == null) {
        mLruCache.put(key, bitmap);
    }
}

public Bitmap getBitmapFromMemCache(String key) {
    return mLruCache.get(key);
}

class BitmapWorkerTask extends AsyncTask<String, Void, Bitmap> {

    private final WeakReference<ImageView> imageViewReference;

    public BitmapWorkerTask(ImageView imageView) {
        // Use a WeakReference to ensure the ImageView can be garbage collected
        imageViewReference = new WeakReference<ImageView>(imageView);
    }

    @Override
    protected Bitmap doInBackground(String... params) {
        final Bitmap bitmap = getScaledImage(params[0]);
        addBitmapToMemoryCache(String.valueOf(params[0]), bitmap);
        return bitmap;
    }

    //  onPostExecute() sets the bitmap fetched by doInBackground();
    @Override
    protected void onPostExecute(Bitmap bitmap) {
        if (imageViewReference != null && bitmap != null) {
            final ImageView imageView = (ImageView)imageViewReference.get();
            if (imageView != null) {
                imageView.setImageBitmap(bitmap);
            }
        }
    }
}
}
0
Bharat Kul Ratan

Bitmap'i kendi Önbellekten kaydedip almak için Utility Class.

package com.roomco.Android.utils;

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


public class MyCache {

      private static MyCache instance;
      private LruCache<Object, Object> lru;

      private MyCache() {

         lru = new LruCache<Object, Object>(1024);

       }

    public static MyCache getInstance() {

        if (instance == null) {
        instance = new MyCache();
       }
       return instance;

    }

   public LruCache<Object, Object> getLru() {
       return lru;
   }

  public void saveBitmapToCahche(String key, Bitmap bitmap){

      MyCache.getInstance().getLru().put(key, bitmap);
  }

  public Bitmap retrieveBitmapFromCache(String key){

      Bitmap bitmap = (Bitmap)MyCache.getInstance().getLru().get(key);
      return bitmap;
  }

}

Kullanımı:

//Save bitmap in cache
MyCache.getInstance().saveBitmapToCahche("your_key",bitmap);
// Get bitmap from cache
MyCache.getInstance().retrieveBitmapFromCache("your_key");
0