Skip to content

Commit df5919f

Browse files
Adam CohenAndroid (Google) Code Review
authored andcommitted
Merge "Fixing cache pruning to avoid pruning those in the visible range" into jb-dev
2 parents db24231 + 591ff97 commit df5919f

File tree

1 file changed

+53
-34
lines changed

1 file changed

+53
-34
lines changed

core/java/android/widget/RemoteViewsAdapter.java

Lines changed: 53 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,10 @@
1717
package android.widget;
1818

1919
import java.lang.ref.WeakReference;
20+
import java.util.ArrayList;
2021
import java.util.HashMap;
2122
import java.util.HashSet;
2223
import java.util.LinkedList;
23-
2424
import android.appwidget.AppWidgetManager;
2525
import android.content.Context;
2626
import android.content.Intent;
@@ -38,7 +38,6 @@
3838
import android.view.View;
3939
import android.view.View.MeasureSpec;
4040
import android.view.ViewGroup;
41-
import android.widget.RemoteViewsService.RemoteViewsFactory;
4241

4342
import com.android.internal.widget.IRemoteViewsAdapterConnection;
4443
import com.android.internal.widget.IRemoteViewsFactory;
@@ -532,10 +531,9 @@ private RemoteViewsFrameLayout createLoadingView(int position, View convertView,
532531
private static class RemoteViewsIndexMetaData implements Parcelable {
533532
int typeId;
534533
long itemId;
535-
boolean isRequested;
536534

537-
public RemoteViewsIndexMetaData(RemoteViews v, long itemId, boolean requested) {
538-
set(v, itemId, requested);
535+
public RemoteViewsIndexMetaData(RemoteViews v, long itemId) {
536+
set(v, itemId);
539537
}
540538

541539
public RemoteViewsIndexMetaData(Parcel src) {
@@ -554,17 +552,14 @@ public int describeContents() {
554552
return 0;
555553
}
556554

557-
public void set(RemoteViews v, long id, boolean requested) {
555+
public void set(RemoteViews v, long id) {
558556
itemId = id;
559557
if (v != null) {
560558
typeId = v.getLayoutId();
561559
} else {
562560
typeId = 0;
563561
}
564-
isRequested = requested;
565562
}
566-
567-
568563
}
569564

570565
/**
@@ -683,10 +678,11 @@ public int describeContents() {
683678
return 0;
684679
}
685680

686-
public void insert(int position, RemoteViews v, long itemId, boolean isRequested) {
681+
public void insert(int position, RemoteViews v, long itemId,
682+
ArrayList<Integer> visibleWindow) {
687683
// Trim the cache if we go beyond the count
688684
if (mIndexRemoteViews.size() >= mMaxCount) {
689-
mIndexRemoteViews.remove(getFarthestPositionFrom(position));
685+
mIndexRemoteViews.remove(getFarthestPositionFrom(position, visibleWindow));
690686
}
691687

692688
// Trim the cache if we go beyond the available memory size constraints
@@ -697,15 +693,15 @@ public void insert(int position, RemoteViews v, long itemId, boolean isRequested
697693
// remove based on both its position as well as it's current memory usage, as well
698694
// as whether it was directly requested vs. whether it was preloaded by our caching
699695
// mechanism.
700-
mIndexRemoteViews.remove(getFarthestPositionFrom(pruneFromPosition));
696+
mIndexRemoteViews.remove(getFarthestPositionFrom(pruneFromPosition, visibleWindow));
701697
}
702698

703699
// Update the metadata cache
704700
if (mIndexMetaData.containsKey(position)) {
705701
final RemoteViewsIndexMetaData metaData = mIndexMetaData.get(position);
706-
metaData.set(v, itemId, isRequested);
702+
metaData.set(v, itemId);
707703
} else {
708-
mIndexMetaData.put(position, new RemoteViewsIndexMetaData(v, itemId, isRequested));
704+
mIndexMetaData.put(position, new RemoteViewsIndexMetaData(v, itemId));
709705
}
710706
mIndexRemoteViews.put(position, v);
711707
}
@@ -748,29 +744,30 @@ private int getRemoteViewsBitmapMemoryUsage() {
748744
}
749745
return mem;
750746
}
751-
private int getFarthestPositionFrom(int pos) {
747+
748+
private int getFarthestPositionFrom(int pos, ArrayList<Integer> visibleWindow) {
752749
// Find the index farthest away and remove that
753750
int maxDist = 0;
754751
int maxDistIndex = -1;
755-
int maxDistNonRequested = 0;
756-
int maxDistIndexNonRequested = -1;
752+
int maxDistNotVisible = 0;
753+
int maxDistIndexNotVisible = -1;
757754
for (int i : mIndexRemoteViews.keySet()) {
758755
int dist = Math.abs(i-pos);
759-
if (dist > maxDistNonRequested && !mIndexMetaData.get(i).isRequested) {
760-
// maxDistNonRequested/maxDistIndexNonRequested will store the index of the
761-
// farthest non-requested position
762-
maxDistIndexNonRequested = i;
763-
maxDistNonRequested = dist;
756+
if (dist > maxDistNotVisible && !visibleWindow.contains(i)) {
757+
// maxDistNotVisible/maxDistIndexNotVisible will store the index of the
758+
// farthest non-visible position
759+
maxDistIndexNotVisible = i;
760+
maxDistNotVisible = dist;
764761
}
765762
if (dist >= maxDist) {
766763
// maxDist/maxDistIndex will store the index of the farthest position
767-
// regardless of whether it was directly requested or not
764+
// regardless of whether it is visible or not
768765
maxDistIndex = i;
769766
maxDist = dist;
770767
}
771768
}
772-
if (maxDistIndexNonRequested > -1) {
773-
return maxDistIndexNonRequested;
769+
if (maxDistIndexNotVisible > -1) {
770+
return maxDistIndexNotVisible;
774771
}
775772
return maxDistIndex;
776773
}
@@ -967,15 +964,13 @@ public void run() {
967964
if (mServiceConnection.isConnected()) {
968965
// Get the next index to load
969966
int position = -1;
970-
boolean isRequested = false;
971967
synchronized (mCache) {
972968
int[] res = mCache.getNextIndexToLoad();
973969
position = res[0];
974-
isRequested = res[1] > 0;
975970
}
976971
if (position > -1) {
977972
// Load the item, and notify any existing RemoteViewsFrameLayouts
978-
updateRemoteViews(position, isRequested, true);
973+
updateRemoteViews(position, true);
979974

980975
// Queue up for the next one to load
981976
loadNextIndexInBackground();
@@ -1037,8 +1032,7 @@ private void updateTemporaryMetaData() {
10371032
}
10381033
}
10391034

1040-
private void updateRemoteViews(final int position, boolean isRequested, boolean
1041-
notifyWhenLoaded) {
1035+
private void updateRemoteViews(final int position, boolean notifyWhenLoaded) {
10421036
IRemoteViewsFactory factory = mServiceConnection.getRemoteViewsFactory();
10431037

10441038
// Load the item information from the remote service
@@ -1070,13 +1064,17 @@ private void updateRemoteViews(final int position, boolean isRequested, boolean
10701064
int layoutId = remoteViews.getLayoutId();
10711065
RemoteViewsMetaData metaData = mCache.getMetaData();
10721066
boolean viewTypeInRange;
1067+
int cacheCount;
10731068
synchronized (metaData) {
10741069
viewTypeInRange = metaData.isViewTypeInRange(layoutId);
1070+
cacheCount = mCache.mMetaData.count;
10751071
}
10761072
synchronized (mCache) {
10771073
if (viewTypeInRange) {
1074+
ArrayList<Integer> visibleWindow = getVisibleWindow(mVisibleWindowLowerBound,
1075+
mVisibleWindowUpperBound, cacheCount);
10781076
// Cache the RemoteViews we loaded
1079-
mCache.insert(position, remoteViews, itemId, isRequested);
1077+
mCache.insert(position, remoteViews, itemId, visibleWindow);
10801078

10811079
// Notify all the views that we have previously returned for this index that
10821080
// there is new data for it.
@@ -1199,7 +1197,6 @@ public View getView(int position, View convertView, ViewGroup parent) {
11991197
Context context = parent.getContext();
12001198
RemoteViews rv = mCache.getRemoteViewsAt(position);
12011199
RemoteViewsIndexMetaData indexMetaData = mCache.getMetaDataAt(position);
1202-
indexMetaData.isRequested = true;
12031200
int typeId = indexMetaData.typeId;
12041201

12051202
try {
@@ -1298,18 +1295,21 @@ private void onNotifyDataSetChanged() {
12981295
// Re-request the new metadata (only after the notification to the factory)
12991296
updateTemporaryMetaData();
13001297
int newCount;
1298+
ArrayList<Integer> visibleWindow;
13011299
synchronized(mCache.getTemporaryMetaData()) {
13021300
newCount = mCache.getTemporaryMetaData().count;
1301+
visibleWindow = getVisibleWindow(mVisibleWindowLowerBound,
1302+
mVisibleWindowUpperBound, newCount);
13031303
}
13041304

13051305
// Pre-load (our best guess of) the views which are currently visible in the AdapterView.
13061306
// This mitigates flashing and flickering of loading views when a widget notifies that
13071307
// its data has changed.
1308-
for (int i = mVisibleWindowLowerBound; i <= mVisibleWindowUpperBound; i++) {
1308+
for (int i: visibleWindow) {
13091309
// Because temporary meta data is only ever modified from this thread (ie.
13101310
// mWorkerThread), it is safe to assume that count is a valid representation.
13111311
if (i < newCount) {
1312-
updateRemoteViews(i, false, false);
1312+
updateRemoteViews(i, false);
13131313
}
13141314
}
13151315

@@ -1330,6 +1330,25 @@ public void run() {
13301330
mNotifyDataSetChangedAfterOnServiceConnected = false;
13311331
}
13321332

1333+
private ArrayList<Integer> getVisibleWindow(int lower, int upper, int count) {
1334+
ArrayList<Integer> window = new ArrayList<Integer>();
1335+
if (lower <= upper) {
1336+
for (int i = lower; i <= upper; i++){
1337+
window.add(i);
1338+
}
1339+
} else {
1340+
// If the upper bound is less than the lower bound it means that the visible window
1341+
// wraps around.
1342+
for (int i = lower; i < count; i++) {
1343+
window.add(i);
1344+
}
1345+
for (int i = 0; i <= upper; i++) {
1346+
window.add(i);
1347+
}
1348+
}
1349+
return window;
1350+
}
1351+
13331352
public void notifyDataSetChanged() {
13341353
// Dequeue any unbind messages
13351354
mMainQueue.removeMessages(sUnbindServiceMessageType);

0 commit comments

Comments
 (0)