diff options
author | Adam Cohen <adamcohen@google.com> | 2011-07-14 15:55:55 -0700 |
---|---|---|
committer | Android (Google) Code Review <android-gerrit@google.com> | 2011-07-14 15:55:55 -0700 |
commit | d4ee810dce69698efd5a839c450823161276dfd7 (patch) | |
tree | 1d9b54f15fff24c14e9eac06db75ca896d4e292d | |
parent | fbaa1ea13cf4ebf95f6b4228219d9385781127e5 (diff) | |
parent | b7ffea697292e48c9d764c5677b69af484e045c8 (diff) | |
download | frameworks_base-d4ee810dce69698efd5a839c450823161276dfd7.zip frameworks_base-d4ee810dce69698efd5a839c450823161276dfd7.tar.gz frameworks_base-d4ee810dce69698efd5a839c450823161276dfd7.tar.bz2 |
Merge "Catching RemoteViews#apply() layout inflation exceptions in RemoteViewsAdapter"
-rw-r--r-- | core/java/android/widget/RemoteViewsAdapter.java | 92 |
1 files changed, 65 insertions, 27 deletions
diff --git a/core/java/android/widget/RemoteViewsAdapter.java b/core/java/android/widget/RemoteViewsAdapter.java index 4c47d37..867ebb4 100644 --- a/core/java/android/widget/RemoteViewsAdapter.java +++ b/core/java/android/widget/RemoteViewsAdapter.java @@ -53,6 +53,10 @@ public class RemoteViewsAdapter extends BaseAdapter implements Handler.Callback // This ensures that we don't stay continually bound to the service and that it can be destroyed // if we need the memory elsewhere in the system. private static final int sUnbindServiceDelay = 5000; + + // Default height for the default loading view, in case we cannot get inflate the first view + private static final int sDefaultLoadingViewHeight = 50; + // Type defs for controlling different messages across the main and worker message queues private static final int sDefaultMessageType = 0; private static final int sUnbindServiceMessageType = 1; @@ -386,21 +390,39 @@ public class RemoteViewsAdapter extends BaseAdapter implements Handler.Callback // Create a new loading view synchronized (mCache) { + boolean customLoadingViewAvailable = false; + if (mUserLoadingView != null) { - // A user-specified loading view - View loadingView = mUserLoadingView.apply(parent.getContext(), parent); - loadingView.setTagInternal(com.android.internal.R.id.rowTypeId, new Integer(0)); - layout.addView(loadingView); - } else { + // Try to inflate user-specified loading view + try { + View loadingView = mUserLoadingView.apply(parent.getContext(), parent); + loadingView.setTagInternal(com.android.internal.R.id.rowTypeId, + new Integer(0)); + layout.addView(loadingView); + customLoadingViewAvailable = true; + } catch (Exception e) { + Log.w(TAG, "Error inflating custom loading view, using default loading" + + "view instead", e); + } + } + if (!customLoadingViewAvailable) { // A default loading view // Use the size of the first row as a guide for the size of the loading view if (mFirstViewHeight < 0) { - View firstView = mFirstView.apply(parent.getContext(), parent); - firstView.measure( - MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED), - MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED)); - mFirstViewHeight = firstView.getMeasuredHeight(); - mFirstView = null; + try { + View firstView = mFirstView.apply(parent.getContext(), parent); + firstView.measure( + MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED), + MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED)); + mFirstViewHeight = firstView.getMeasuredHeight(); + mFirstView = null; + } catch (Exception e) { + float density = mContext.getResources().getDisplayMetrics().density; + mFirstViewHeight = (int) + Math.round(sDefaultLoadingViewHeight * density); + mFirstView = null; + Log.w(TAG, "Error inflating first RemoteViews" + e); + } } // Compose the loading view text @@ -937,24 +959,40 @@ public class RemoteViewsAdapter extends BaseAdapter implements Handler.Callback indexMetaData.isRequested = true; int typeId = indexMetaData.typeId; - // Reuse the convert view where possible - if (layout != null) { - if (convertViewTypeId == typeId) { - rv.reapply(context, convertViewChild); - return layout; + try { + // Reuse the convert view where possible + if (layout != null) { + if (convertViewTypeId == typeId) { + rv.reapply(context, convertViewChild); + return layout; + } + layout.removeAllViews(); + } else { + layout = new RemoteViewsFrameLayout(context); } - layout.removeAllViews(); - } else { - layout = new RemoteViewsFrameLayout(context); - } - // Otherwise, create a new view to be returned - View newView = rv.apply(context, parent); - newView.setTagInternal(com.android.internal.R.id.rowTypeId, new Integer(typeId)); - layout.addView(newView); - if (hasNewItems) loadNextIndexInBackground(); - - return layout; + // Otherwise, create a new view to be returned + View newView = rv.apply(context, parent); + newView.setTagInternal(com.android.internal.R.id.rowTypeId, + new Integer(typeId)); + layout.addView(newView); + return layout; + + } catch (Exception e){ + // We have to make sure that we successfully inflated the RemoteViews, if not + // we return the loading view instead. + Log.w(TAG, "Error inflating RemoteViews at position: " + position + ", using" + + "loading view instead" + e); + + RemoteViewsFrameLayout loadingView = null; + final RemoteViewsMetaData metaData = mCache.getMetaData(); + synchronized (metaData) { + loadingView = metaData.createLoadingView(position, convertView, parent); + } + return loadingView; + } finally { + if (hasNewItems) loadNextIndexInBackground(); + } } else { // If the cache does not have the RemoteViews at this position, then create a // loading view and queue the actual position to be loaded in the background |