SerialBitmapReferenceCounter.java revision ac28599e2b40e0dd6b97f6a91849585531264622
1package com.bumptech.glide.load.engine.bitmap_recycle; 2 3import android.graphics.Bitmap; 4 5import java.util.LinkedList; 6import java.util.Map; 7import java.util.WeakHashMap; 8 9public class SerialBitmapReferenceCounter implements BitmapReferenceCounter { 10 11 private static class InnerTrackerPool { 12 private LinkedList<InnerTracker> pool = new LinkedList<InnerTracker>(); 13 14 public InnerTracker get() { 15 InnerTracker result = pool.poll(); 16 if (result == null) { 17 result = new InnerTracker(); 18 } 19 20 return result; 21 } 22 23 public void release(InnerTracker innerTracker) { 24 pool.offer(innerTracker); 25 } 26 } 27 28 private static class InnerTracker { 29 private int refs = 0; 30 31 public void acquire() { 32 refs++; 33 } 34 35 public boolean release() { 36 refs--; 37 38 return refs == 0; 39 } 40 } 41 42 private final Map<Bitmap, InnerTracker> counter = new WeakHashMap<Bitmap, InnerTracker>(); 43 private final BitmapPool target; 44 private final InnerTrackerPool pool = new InnerTrackerPool(); 45 46 public SerialBitmapReferenceCounter(BitmapPool target) { 47 this.target = target; 48 } 49 50 private void initBitmap(Bitmap toInit) { 51 final InnerTracker tracker = counter.get(toInit); 52 if (tracker == null) { 53 counter.put(toInit, pool.get()); 54 } 55 } 56 57 @Override 58 public void acquireBitmap(Bitmap bitmap) { 59 initBitmap(bitmap); 60 counter.get(bitmap).acquire(); 61 } 62 63 @Override 64 public void releaseBitmap(Bitmap bitmap) { 65 final InnerTracker tracker = counter.get(bitmap); 66 if (tracker.release()) { 67 recycle(tracker, bitmap); 68 } 69 } 70 71 private void recycle(InnerTracker tracker, Bitmap bitmap) { 72 if (!target.put(bitmap)) { 73 bitmap.recycle(); 74 } 75 counter.remove(bitmap); 76 pool.release(tracker); 77 } 78} 79