2929import android .os .IBinder ;
3030import android .os .Looper ;
3131import android .os .Message ;
32- import android .os .Parcel ;
33- import android .os .Parcelable ;
3432import android .os .RemoteException ;
3533import android .util .Log ;
3634import android .util .Pair ;
5048public class RemoteViewsAdapter extends BaseAdapter implements Handler .Callback {
5149 private static final String TAG = "RemoteViewsAdapter" ;
5250
53- // The max number of items in the cache
51+ // The max number of items in the cache
5452 private static final int sDefaultCacheSize = 40 ;
5553 // The delay (in millis) to wait until attempting to unbind from a service after a request.
5654 // This ensures that we don't stay continually bound to the service and that it can be destroyed
@@ -61,7 +59,7 @@ public class RemoteViewsAdapter extends BaseAdapter implements Handler.Callback
6159 private static final int sDefaultLoadingViewHeight = 50 ;
6260
6361 // Type defs for controlling different messages across the main and worker message queues
64- private static final int sDefaultMessageType = 0 ;
62+ private static final int sDefaultMessageType = 0 ;
6563 private static final int sUnbindServiceMessageType = 1 ;
6664
6765 private final Context mContext ;
@@ -88,9 +86,9 @@ public class RemoteViewsAdapter extends BaseAdapter implements Handler.Callback
8886
8987 // We cache the FixedSizeRemoteViewsCaches across orientation. These are the related data
9088 // structures;
91- private static final HashMap <Pair <Intent .FilterComparison , Integer >, Parcel >
89+ private static final HashMap <Pair <Intent .FilterComparison , Integer >, FixedSizeRemoteViewsCache >
9290 sCachedRemoteViewsCaches = new HashMap <Pair <Intent .FilterComparison , Integer >,
93- Parcel >();
91+ FixedSizeRemoteViewsCache >();
9492 private static final HashMap <Pair <Intent .FilterComparison , Integer >, Runnable >
9593 sRemoteViewsCacheRemoveRunnables = new HashMap <Pair <Intent .FilterComparison , Integer >,
9694 Runnable >();
@@ -354,7 +352,7 @@ public void clear() {
354352 /**
355353 * The meta-data associated with the cache in it's current state.
356354 */
357- private static class RemoteViewsMetaData implements Parcelable {
355+ private static class RemoteViewsMetaData {
358356 int count ;
359357 int viewTypeCount ;
360358 boolean hasStableIds ;
@@ -373,51 +371,6 @@ public RemoteViewsMetaData() {
373371 reset ();
374372 }
375373
376- public RemoteViewsMetaData (Parcel src ) {
377- count = src .readInt ();
378- viewTypeCount = src .readInt ();
379- hasStableIds = src .readInt () == 0 ? false : true ;
380- mFirstViewHeight = src .readInt ();
381- if (src .readInt () != 0 ) {
382- mUserLoadingView = new RemoteViews (src );
383- }
384- if (src .readInt () != 0 ) {
385- mFirstView = new RemoteViews (src );
386- }
387- int count = src .readInt ();
388- for (int i = 0 ; i < count ; i ++) {
389- mTypeIdIndexMap .put (src .readInt (), src .readInt ());
390- }
391- }
392-
393- @ Override
394- public void writeToParcel (Parcel dest , int flags ) {
395- dest .writeInt (count );
396- dest .writeInt (viewTypeCount );
397- dest .writeInt (hasStableIds ? 1 : 0 );
398- dest .writeInt (mFirstViewHeight );
399- dest .writeInt (mUserLoadingView != null ? 1 : 0 );
400- if (mUserLoadingView != null ) {
401- mUserLoadingView .writeToParcel (dest , flags );
402- }
403- dest .writeInt (mFirstView != null ? 1 : 0 );
404- if (mFirstView != null ) {
405- mFirstView .writeToParcel (dest , flags );
406- }
407-
408- int count = mTypeIdIndexMap .size ();
409- dest .writeInt (count );
410- for (Integer key : mTypeIdIndexMap .keySet ()) {
411- dest .writeInt (key );
412- dest .writeInt (mTypeIdIndexMap .get (key ));
413- }
414- }
415-
416- @ Override
417- public int describeContents () {
418- return 0 ;
419- }
420-
421374 public void set (RemoteViewsMetaData d ) {
422375 synchronized (d ) {
423376 count = d .count ;
@@ -528,30 +481,14 @@ private RemoteViewsFrameLayout createLoadingView(int position, View convertView,
528481 /**
529482 * The meta-data associated with a single item in the cache.
530483 */
531- private static class RemoteViewsIndexMetaData implements Parcelable {
484+ private static class RemoteViewsIndexMetaData {
532485 int typeId ;
533486 long itemId ;
534487
535488 public RemoteViewsIndexMetaData (RemoteViews v , long itemId ) {
536489 set (v , itemId );
537490 }
538491
539- public RemoteViewsIndexMetaData (Parcel src ) {
540- typeId = src .readInt ();
541- itemId = src .readLong ();
542- }
543-
544- @ Override
545- public void writeToParcel (Parcel dest , int flags ) {
546- dest .writeInt (typeId );
547- dest .writeLong (itemId );
548- }
549-
550- @ Override
551- public int describeContents () {
552- return 0 ;
553- }
554-
555492 public void set (RemoteViews v , long id ) {
556493 itemId = id ;
557494 if (v != null ) {
@@ -565,7 +502,7 @@ public void set(RemoteViews v, long id) {
565502 /**
566503 *
567504 */
568- private static class FixedSizeRemoteViewsCache implements Parcelable {
505+ private static class FixedSizeRemoteViewsCache {
569506 private static final String TAG = "FixedSizeRemoteViewsCache" ;
570507
571508 // The meta data related to all the RemoteViews, ie. count, is stable, etc.
@@ -627,57 +564,6 @@ public FixedSizeRemoteViewsCache(int maxCacheSize) {
627564 mLoadIndices = new HashSet <Integer >();
628565 }
629566
630- public FixedSizeRemoteViewsCache (Parcel src ) {
631- mMaxCount = src .readInt ();
632- mMaxCountSlack = src .readInt ();
633- mPreloadLowerBound = src .readInt ();
634- mPreloadUpperBound = src .readInt ();
635- mMetaData = new RemoteViewsMetaData (src );
636- int count = src .readInt ();
637- mIndexMetaData = new HashMap <Integer , RemoteViewsIndexMetaData >();
638- for (int i = 0 ; i < count ; i ++) {
639- mIndexMetaData .put (src .readInt (), new RemoteViewsIndexMetaData (src ));
640- }
641- count = src .readInt ();
642- mIndexRemoteViews = new HashMap <Integer , RemoteViews >();
643- for (int i = 0 ; i < count ; i ++) {
644- mIndexRemoteViews .put (src .readInt (), new RemoteViews (src ));
645- }
646-
647- mTemporaryMetaData = new RemoteViewsMetaData ();
648- mRequestedIndices = new HashSet <Integer >();
649- mLastRequestedIndex = -1 ;
650- mLoadIndices = new HashSet <Integer >();
651- }
652-
653- @ Override
654- public void writeToParcel (Parcel dest , int flags ) {
655- dest .writeInt (mMaxCount );
656- dest .writeInt (mMaxCountSlack );
657- dest .writeInt (mPreloadLowerBound );
658- dest .writeInt (mPreloadUpperBound );
659- mMetaData .writeToParcel (dest , 0 );
660-
661- // We write the index data and cache
662- int count = mIndexMetaData .size ();
663- dest .writeInt (count );
664- for (Integer key : mIndexMetaData .keySet ()) {
665- dest .writeInt (key );
666- mIndexMetaData .get (key ).writeToParcel (dest , flags );
667- }
668- count = mIndexRemoteViews .size ();
669- dest .writeInt (count );
670- for (Integer key : mIndexRemoteViews .keySet ()) {
671- dest .writeInt (key );
672- mIndexRemoteViews .get (key ).writeToParcel (dest , flags );
673- }
674- }
675-
676- @ Override
677- public int describeContents () {
678- return 0 ;
679- }
680-
681567 public void insert (int position , RemoteViews v , long itemId ,
682568 ArrayList <Integer > visibleWindow ) {
683569 // Trim the cache if we go beyond the count
@@ -897,12 +783,18 @@ public RemoteViewsAdapter(Context context, Intent intent, RemoteAdapterConnectio
897783
898784 synchronized (sCachedRemoteViewsCaches ) {
899785 if (sCachedRemoteViewsCaches .containsKey (key )) {
900- Parcel src = sCachedRemoteViewsCaches .get (key );
901- src .setDataPosition (0 );
902- mCache = new FixedSizeRemoteViewsCache (src );
903- mDataReady = true ;
786+ mCache = sCachedRemoteViewsCaches .get (key );
787+ synchronized (mCache .mMetaData ) {
788+ if (mCache .mMetaData .count > 0 ) {
789+ // As a precautionary measure, we verify that the meta data indicates a
790+ // non-zero count before declaring that data is ready.
791+ mDataReady = true ;
792+ }
793+ }
904794 } else {
905795 mCache = new FixedSizeRemoteViewsCache (sDefaultCacheSize );
796+ }
797+ if (!mDataReady ) {
906798 requestBindService ();
907799 }
908800 }
@@ -934,11 +826,18 @@ public void saveRemoteViewsCache() {
934826 sRemoteViewsCacheRemoveRunnables .remove (key );
935827 }
936828
937- Parcel p = Parcel .obtain ();
938- synchronized (mCache ) {
939- mCache .writeToParcel (p , 0 );
829+ int metaDataCount = 0 ;
830+ int numRemoteViewsCached = 0 ;
831+ synchronized (mCache .mMetaData ) {
832+ metaDataCount = mCache .mMetaData .count ;
940833 }
941- sCachedRemoteViewsCaches .put (key , p );
834+ synchronized (mCache ) {
835+ numRemoteViewsCached = mCache .mIndexRemoteViews .size ();
836+ }
837+ if (metaDataCount > 0 && numRemoteViewsCached > 0 ) {
838+ sCachedRemoteViewsCaches .put (key , mCache );
839+ }
840+
942841 Runnable r = new Runnable () {
943842 @ Override
944843 public void run () {
@@ -1332,6 +1231,12 @@ public void run() {
13321231
13331232 private ArrayList <Integer > getVisibleWindow (int lower , int upper , int count ) {
13341233 ArrayList <Integer > window = new ArrayList <Integer >();
1234+
1235+ // In the case that the window is invalid or uninitialized, return an empty window.
1236+ if ((lower == 0 && upper == 0 ) || lower < 0 || upper < 0 ) {
1237+ return window ;
1238+ }
1239+
13351240 if (lower <= upper ) {
13361241 for (int i = lower ; i <= upper ; i ++){
13371242 window .add (i );
0 commit comments