@@ -246,7 +246,7 @@ public synchronized boolean isConnected() {
246246 * A FrameLayout which contains a loading view, and manages the re/applying of RemoteViews when
247247 * they are loaded.
248248 */
249- private class RemoteViewsFrameLayout extends FrameLayout {
249+ private static class RemoteViewsFrameLayout extends FrameLayout {
250250 public RemoteViewsFrameLayout (Context context ) {
251251 super (context );
252252 }
@@ -301,7 +301,7 @@ public void add(int position, RemoteViewsFrameLayout layout) {
301301 * Notifies each of the RemoteViewsFrameLayouts associated with a particular position that
302302 * the associated RemoteViews has loaded.
303303 */
304- public void notifyOnRemoteViewsLoaded (int position , RemoteViews view , int typeId ) {
304+ public void notifyOnRemoteViewsLoaded (int position , RemoteViews view ) {
305305 if (view == null ) return ;
306306
307307 final Integer pos = position ;
@@ -331,7 +331,7 @@ public void clear() {
331331 /**
332332 * The meta-data associated with the cache in it's current state.
333333 */
334- private class RemoteViewsMetaData {
334+ private static class RemoteViewsMetaData {
335335 int count ;
336336 int viewTypeCount ;
337337 boolean hasStableIds ;
@@ -390,14 +390,23 @@ public int getMappedViewType(int typeId) {
390390 }
391391 }
392392
393+ public boolean isViewTypeInRange (int typeId ) {
394+ int mappedType = getMappedViewType (typeId );
395+ if (mappedType >= viewTypeCount ) {
396+ return false ;
397+ } else {
398+ return true ;
399+ }
400+ }
401+
393402 private RemoteViewsFrameLayout createLoadingView (int position , View convertView ,
394- ViewGroup parent ) {
403+ ViewGroup parent , Object lock , LayoutInflater layoutInflater ) {
395404 // Create and return a new FrameLayout, and setup the references for this position
396405 final Context context = parent .getContext ();
397406 RemoteViewsFrameLayout layout = new RemoteViewsFrameLayout (context );
398407
399408 // Create a new loading view
400- synchronized (mCache ) {
409+ synchronized (lock ) {
401410 boolean customLoadingViewAvailable = false ;
402411
403412 if (mUserLoadingView != null ) {
@@ -425,7 +434,7 @@ private RemoteViewsFrameLayout createLoadingView(int position, View convertView,
425434 mFirstViewHeight = firstView .getMeasuredHeight ();
426435 mFirstView = null ;
427436 } catch (Exception e ) {
428- float density = mContext .getResources ().getDisplayMetrics ().density ;
437+ float density = context .getResources ().getDisplayMetrics ().density ;
429438 mFirstViewHeight = (int )
430439 Math .round (sDefaultLoadingViewHeight * density );
431440 mFirstView = null ;
@@ -434,7 +443,7 @@ private RemoteViewsFrameLayout createLoadingView(int position, View convertView,
434443 }
435444
436445 // Compose the loading view text
437- TextView loadingTextView = (TextView ) mLayoutInflater .inflate (
446+ TextView loadingTextView = (TextView ) layoutInflater .inflate (
438447 com .android .internal .R .layout .remote_views_adapter_default_loading_view ,
439448 layout , false );
440449 loadingTextView .setHeight (mFirstViewHeight );
@@ -451,7 +460,7 @@ private RemoteViewsFrameLayout createLoadingView(int position, View convertView,
451460 /**
452461 * The meta-data associated with a single item in the cache.
453462 */
454- private class RemoteViewsIndexMetaData {
463+ private static class RemoteViewsIndexMetaData {
455464 int typeId ;
456465 long itemId ;
457466 boolean isRequested ;
@@ -462,18 +471,19 @@ public RemoteViewsIndexMetaData(RemoteViews v, long itemId, boolean requested) {
462471
463472 public void set (RemoteViews v , long id , boolean requested ) {
464473 itemId = id ;
465- if (v != null )
474+ if (v != null ) {
466475 typeId = v .getLayoutId ();
467- else
476+ } else {
468477 typeId = 0 ;
478+ }
469479 isRequested = requested ;
470480 }
471481 }
472482
473483 /**
474484 *
475485 */
476- private class FixedSizeRemoteViewsCache {
486+ private static class FixedSizeRemoteViewsCache {
477487 private static final String TAG = "FixedSizeRemoteViewsCache" ;
478488
479489 // The meta data related to all the RemoteViews, ie. count, is stable, etc.
@@ -861,21 +871,36 @@ private void updateRemoteViews(final int position, boolean isRequested, boolean
861871 "returned from RemoteViewsFactory." );
862872 return ;
863873 }
874+
875+ int layoutId = remoteViews .getLayoutId ();
876+ RemoteViewsMetaData metaData = mCache .getMetaData ();
877+ boolean viewTypeInRange ;
878+ synchronized (metaData ) {
879+ viewTypeInRange = metaData .isViewTypeInRange (layoutId );
880+ }
864881 synchronized (mCache ) {
865- // Cache the RemoteViews we loaded
866- mCache .insert (position , remoteViews , itemId , isRequested );
867-
868- // Notify all the views that we have previously returned for this index that
869- // there is new data for it.
870- final RemoteViews rv = remoteViews ;
871- final int typeId = mCache .getMetaDataAt (position ).typeId ;
872- if (notifyWhenLoaded ) {
873- mMainQueue .post (new Runnable () {
874- @ Override
875- public void run () {
876- mRequestedViews .notifyOnRemoteViewsLoaded (position , rv , typeId );
877- }
878- });
882+ if (viewTypeInRange ) {
883+ // Cache the RemoteViews we loaded
884+ mCache .insert (position , remoteViews , itemId , isRequested );
885+
886+ // Notify all the views that we have previously returned for this index that
887+ // there is new data for it.
888+ final RemoteViews rv = remoteViews ;
889+ if (notifyWhenLoaded ) {
890+ mMainQueue .post (new Runnable () {
891+ @ Override
892+ public void run () {
893+ mRequestedViews .notifyOnRemoteViewsLoaded (position , rv );
894+ }
895+ });
896+ }
897+ } else {
898+ // We need to log an error here, as the the view type count specified by the
899+ // factory is less than the number of view types returned. We don't return this
900+ // view to the AdapterView, as this will cause an exception in the hosting process,
901+ // which contains the associated AdapterView.
902+ Log .e (TAG , "Error: widget's RemoteViewsFactory returns more view types than " +
903+ " indicated by getViewTypeCount() " );
879904 }
880905 }
881906 }
@@ -1010,7 +1035,8 @@ public View getView(int position, View convertView, ViewGroup parent) {
10101035 RemoteViewsFrameLayout loadingView = null ;
10111036 final RemoteViewsMetaData metaData = mCache .getMetaData ();
10121037 synchronized (metaData ) {
1013- loadingView = metaData .createLoadingView (position , convertView , parent );
1038+ loadingView = metaData .createLoadingView (position , convertView , parent ,
1039+ mCache , mLayoutInflater );
10141040 }
10151041 return loadingView ;
10161042 } finally {
@@ -1022,7 +1048,8 @@ public View getView(int position, View convertView, ViewGroup parent) {
10221048 RemoteViewsFrameLayout loadingView = null ;
10231049 final RemoteViewsMetaData metaData = mCache .getMetaData ();
10241050 synchronized (metaData ) {
1025- loadingView = metaData .createLoadingView (position , convertView , parent );
1051+ loadingView = metaData .createLoadingView (position , convertView , parent ,
1052+ mCache , mLayoutInflater );
10261053 }
10271054
10281055 mRequestedViews .add (position , loadingView );
0 commit comments