diff options
Diffstat (limited to 'core')
-rw-r--r-- | core/java/android/widget/ProgressBar.java | 123 |
1 files changed, 98 insertions, 25 deletions
diff --git a/core/java/android/widget/ProgressBar.java b/core/java/android/widget/ProgressBar.java index 3bc4f7f..0b49404 100644 --- a/core/java/android/widget/ProgressBar.java +++ b/core/java/android/widget/ProgressBar.java @@ -37,9 +37,11 @@ import android.graphics.drawable.shapes.RoundRectShape; import android.graphics.drawable.shapes.Shape; import android.os.Parcel; import android.os.Parcelable; -import android.os.SystemClock; import android.util.AttributeSet; -import android.view.Choreographer; +import android.util.Pool; +import android.util.Poolable; +import android.util.PoolableManager; +import android.util.Pools; import android.view.Gravity; import android.view.RemotableViewMethod; import android.view.View; @@ -55,6 +57,8 @@ import android.view.animation.LinearInterpolator; import android.view.animation.Transformation; import android.widget.RemoteViews.RemoteView; +import java.util.ArrayList; + /** * <p> @@ -218,6 +222,10 @@ public class ProgressBar extends View { private boolean mShouldStartAnimationDrawable; private boolean mInDrawing; + private boolean mAttached; + private boolean mRefreshIsPosted; + + private final ArrayList<RefreshData> mRefreshData = new ArrayList<RefreshData>(); private AccessibilityEventSender mAccessibilityEventSender; @@ -558,29 +566,76 @@ public class ProgressBar extends View { } private class RefreshProgressRunnable implements Runnable { + public void run() { + synchronized (ProgressBar.this) { + final int count = mRefreshData.size(); + for (int i = 0; i < count; i++) { + final RefreshData rd = mRefreshData.get(i); + doRefreshProgress(rd.id, rd.progress, rd.fromUser, true); + rd.recycle(); + } + mRefreshData.clear(); + mRefreshIsPosted = false; + } + } + } - private int mId; - private int mProgress; - private boolean mFromUser; + private static class RefreshData implements Poolable<RefreshData> { + public int id; + public int progress; + public boolean fromUser; - RefreshProgressRunnable(int id, int progress, boolean fromUser) { - mId = id; - mProgress = progress; - mFromUser = fromUser; - } + private RefreshData mNext; + private boolean mIsPooled; - public void run() { - doRefreshProgress(mId, mProgress, mFromUser, true); - // Put ourselves back in the cache when we are done - mRefreshProgressRunnable = this; + private static final int POOL_MAX = 24; + private static final Pool<RefreshData> sPool = Pools.synchronizedPool( + Pools.finitePool(new PoolableManager<RefreshData>() { + @Override + public RefreshData newInstance() { + return new RefreshData(); + } + + @Override + public void onAcquired(RefreshData element) { + } + + @Override + public void onReleased(RefreshData element) { + } + }, POOL_MAX)); + + public static RefreshData obtain(int id, int progress, boolean fromUser) { + RefreshData rd = sPool.acquire(); + rd.id = id; + rd.progress = progress; + rd.fromUser = fromUser; + return rd; } - public void setup(int id, int progress, boolean fromUser) { - mId = id; - mProgress = progress; - mFromUser = fromUser; + public void recycle() { + sPool.release(this); + } + + @Override + public void setNextPoolable(RefreshData element) { + mNext = element; + } + + @Override + public RefreshData getNextPoolable() { + return mNext; + } + + @Override + public boolean isPooled() { + return mIsPooled; + } + + @Override + public void setPooled(boolean isPooled) { + mIsPooled = isPooled; } - } private synchronized void doRefreshProgress(int id, int progress, boolean fromUser, @@ -619,14 +674,16 @@ public class ProgressBar extends View { if (mRefreshProgressRunnable != null) { // Use cached RefreshProgressRunnable if available r = mRefreshProgressRunnable; - // Uncache it - mRefreshProgressRunnable = null; - r.setup(id, progress, fromUser); } else { // Make a new one - r = new RefreshProgressRunnable(id, progress, fromUser); + r = new RefreshProgressRunnable(); + } + final RefreshData rd = RefreshData.obtain(id, progress, fromUser); + mRefreshData.add(rd); + if (mAttached && !mRefreshIsPosted) { + post(r); + mRefreshIsPosted = true; } - post(r); } } @@ -1092,6 +1149,18 @@ public class ProgressBar extends View { if (mIndeterminate) { startAnimation(); } + if (mRefreshData != null) { + synchronized (this) { + final int count = mRefreshData.size(); + for (int i = 0; i < count; i++) { + final RefreshData rd = mRefreshData.get(i); + doRefreshProgress(rd.id, rd.progress, rd.fromUser, true); + rd.recycle(); + } + mRefreshData.clear(); + } + } + mAttached = true; } @Override @@ -1099,7 +1168,10 @@ public class ProgressBar extends View { if (mIndeterminate) { stopAnimation(); } - if(mRefreshProgressRunnable != null) { + if (mRefreshProgressRunnable != null) { + removeCallbacks(mRefreshProgressRunnable); + } + if (mRefreshProgressRunnable != null && mRefreshIsPosted) { removeCallbacks(mRefreshProgressRunnable); } if (mAccessibilityEventSender != null) { @@ -1108,6 +1180,7 @@ public class ProgressBar extends View { // This should come after stopAnimation(), otherwise an invalidate message remains in the // queue, which can prevent the entire view hierarchy from being GC'ed during a rotation super.onDetachedFromWindow(); + mAttached = false; } @Override |