@@ -477,8 +477,11 @@ private class FixedSizeRemoteViewsCache {
477477 private static final String TAG = "FixedSizeRemoteViewsCache" ;
478478
479479 // The meta data related to all the RemoteViews, ie. count, is stable, etc.
480- private RemoteViewsMetaData mMetaData ;
481- private RemoteViewsMetaData mTemporaryMetaData ;
480+ // The meta data objects are made final so that they can be locked on independently
481+ // of the FixedSizeRemoteViewsCache. If we ever lock on both meta data objects, it is in
482+ // the order mTemporaryMetaData followed by mMetaData.
483+ private final RemoteViewsMetaData mMetaData ;
484+ private final RemoteViewsMetaData mTemporaryMetaData ;
482485
483486 // The cache/mapping of position to RemoteViewsMetaData. This set is guaranteed to be
484487 // greater than or equal to the set of RemoteViews.
@@ -939,6 +942,10 @@ private int getConvertViewTypeId(View convertView) {
939942 * which wouldn't otherwise be possible.
940943 */
941944 public void setVisibleRangeHint (int lowerBound , int upperBound ) {
945+ if (lowerBound < 0 || upperBound < 0 ) {
946+ throw new RuntimeException ("Attempted to set invalid range: lowerBound=" +lowerBound +
947+ "," + "upperBound=" +upperBound );
948+ }
942949 mVisibleWindowLowerBound = lowerBound ;
943950 mVisibleWindowUpperBound = upperBound ;
944951 }
@@ -1072,12 +1079,20 @@ private void onNotifyDataSetChanged() {
10721079
10731080 // Re-request the new metadata (only after the notification to the factory)
10741081 updateTemporaryMetaData ();
1082+ int newCount ;
1083+ synchronized (mCache .getTemporaryMetaData ()) {
1084+ newCount = mCache .getTemporaryMetaData ().count ;
1085+ }
10751086
10761087 // Pre-load (our best guess of) the views which are currently visible in the AdapterView.
10771088 // This mitigates flashing and flickering of loading views when a widget notifies that
10781089 // its data has changed.
10791090 for (int i = mVisibleWindowLowerBound ; i <= mVisibleWindowUpperBound ; i ++) {
1080- updateRemoteViews (i , false , false );
1091+ // Because temporary meta data is only ever modified from this thread (ie.
1092+ // mWorkerThread), it is safe to assume that count is a valid representation.
1093+ if (i < newCount ) {
1094+ updateRemoteViews (i , false , false );
1095+ }
10811096 }
10821097
10831098 // Propagate the notification back to the base adapter
0 commit comments