Loading core/java/android/widget/ProgressBar.java +98 −25 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -55,6 +57,8 @@ import android.view.animation.LinearInterpolator; import android.view.animation.Transformation; import android.widget.RemoteViews.RemoteView; import java.util.ArrayList; /** * <p> Loading Loading @@ -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; Loading Loading @@ -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; 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(); } public void run() { doRefreshProgress(mId, mProgress, mFromUser, true); // Put ourselves back in the cache when we are done mRefreshProgressRunnable = this; @Override public void onAcquired(RefreshData element) { } public void setup(int id, int progress, boolean fromUser) { mId = id; mProgress = progress; mFromUser = fromUser; @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 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, Loading Loading @@ -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; } } } Loading Loading @@ -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 Loading @@ -1102,12 +1171,16 @@ public class ProgressBar extends View { if (mRefreshProgressRunnable != null) { removeCallbacks(mRefreshProgressRunnable); } if (mRefreshProgressRunnable != null && mRefreshIsPosted) { removeCallbacks(mRefreshProgressRunnable); } if (mAccessibilityEventSender != null) { removeCallbacks(mAccessibilityEventSender); } // 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 Loading Loading
core/java/android/widget/ProgressBar.java +98 −25 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -55,6 +57,8 @@ import android.view.animation.LinearInterpolator; import android.view.animation.Transformation; import android.widget.RemoteViews.RemoteView; import java.util.ArrayList; /** * <p> Loading Loading @@ -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; Loading Loading @@ -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; 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(); } public void run() { doRefreshProgress(mId, mProgress, mFromUser, true); // Put ourselves back in the cache when we are done mRefreshProgressRunnable = this; @Override public void onAcquired(RefreshData element) { } public void setup(int id, int progress, boolean fromUser) { mId = id; mProgress = progress; mFromUser = fromUser; @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 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, Loading Loading @@ -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; } } } Loading Loading @@ -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 Loading @@ -1102,12 +1171,16 @@ public class ProgressBar extends View { if (mRefreshProgressRunnable != null) { removeCallbacks(mRefreshProgressRunnable); } if (mRefreshProgressRunnable != null && mRefreshIsPosted) { removeCallbacks(mRefreshProgressRunnable); } if (mAccessibilityEventSender != null) { removeCallbacks(mAccessibilityEventSender); } // 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 Loading