diff options
| -rw-r--r-- | core/java/android/widget/RemoteViews.java | 44 |
1 files changed, 27 insertions, 17 deletions
diff --git a/core/java/android/widget/RemoteViews.java b/core/java/android/widget/RemoteViews.java index 2357d13c8d41..f724285df9dc 100644 --- a/core/java/android/widget/RemoteViews.java +++ b/core/java/android/widget/RemoteViews.java @@ -5735,24 +5735,44 @@ public class RemoteViews implements Parcelable, Filter { return previousLayoutId == getLayoutId() && mViewId == overrideId; } - // Note: topLevel should be true only for calls on the topLevel RemoteViews, internal calls - // should set it to false. - private void reapply(Context context, View v, InteractionHandler handler, SizeF size, - ColorResources colorResources, boolean topLevel) { - + /** + * Returns the RemoteViews that should be used in the reapply operation. + * + * If the current RemoteViews has multiple layout, this will select the correct one. + * + * @throws RuntimeException If the current RemoteViews should not be reapplied onto the provided + * View. + */ + private RemoteViews getRemoteViewsToReapply(Context context, View v, @Nullable SizeF size) { RemoteViews rvToApply = getRemoteViewsToApply(context, size); // In the case that a view has this RemoteViews applied in one orientation or size, is // persisted across change, and has the RemoteViews re-applied in a different situation // (orientation or size), we throw an exception, since the layouts may be completely // unrelated. - if (hasMultipleLayouts()) { + // If the ViewID has been changed on the view, or is changed by the RemoteViews, we also + // may throw an exception, as the RemoteViews will probably not apply properly. + // However, we need to let potentially unrelated RemoteViews apply, as this lack of testing + // is already used in production code in some apps. + if (hasMultipleLayouts() + || rvToApply.mViewId != View.NO_ID + || v.getTag(R.id.remote_views_override_id) != null) { if (!rvToApply.canRecycleView(v)) { throw new RuntimeException("Attempting to re-apply RemoteViews to a view that" + " that does not share the same root layout id."); } } + return rvToApply; + } + + // Note: topLevel should be true only for calls on the topLevel RemoteViews, internal calls + // should set it to false. + private void reapply(Context context, View v, InteractionHandler handler, SizeF size, + ColorResources colorResources, boolean topLevel) { + + RemoteViews rvToApply = getRemoteViewsToReapply(context, v, size); + rvToApply.performApply(v, (ViewGroup) v.getParent(), handler, colorResources); // If the parent of the view is has is a root, resolve the recycling. @@ -5789,17 +5809,7 @@ public class RemoteViews implements Parcelable, Filter { public CancellationSignal reapplyAsync(Context context, View v, Executor executor, OnViewAppliedListener listener, InteractionHandler handler, SizeF size, ColorResources colorResources) { - RemoteViews rvToApply = getRemoteViewsToApply(context, size); - - // In the case that a view has this RemoteViews applied in one orientation, is persisted - // across orientation change, and has the RemoteViews re-applied in the new orientation, - // we throw an exception, since the layouts may be completely unrelated. - if (hasMultipleLayouts()) { - if (!rvToApply.canRecycleView(v)) { - throw new RuntimeException("Attempting to re-apply RemoteViews to a view that" + - " that does not share the same root layout id."); - } - } + RemoteViews rvToApply = getRemoteViewsToReapply(context, v, size); return new AsyncApplyTask(rvToApply, (ViewGroup) v.getParent(), context, listener, handler, colorResources, v, true /* topLevel */) |