diff --git a/core/java/android/widget/AbsListView.java b/core/java/android/widget/AbsListView.java index f3dfb770cd8f0..bb13f1d762519 100644 --- a/core/java/android/widget/AbsListView.java +++ b/core/java/android/widget/AbsListView.java @@ -4365,6 +4365,14 @@ public abstract class AbsListView extends AdapterView implements Te * @param intent the intent used to identify the RemoteViewsService for the adapter to connect to. */ public void setRemoteViewsAdapter(Intent intent) { + // Ensure that we don't already have a RemoteViewsAdapter that is bound to an existing + // service handling the specified intent. + Intent.FilterComparison fc = new Intent.FilterComparison(intent); + if (mRemoteAdapter != null && fc.equals(mRemoteAdapter.getRemoteViewsServiceIntent())) { + return; + } + + // Otherwise, create a new RemoteViewsAdapter for binding mRemoteAdapter = new RemoteViewsAdapter(getContext(), intent, this); } diff --git a/core/java/android/widget/AdapterViewAnimator.java b/core/java/android/widget/AdapterViewAnimator.java index 0310a31e5e63c..c08adb2e56121 100644 --- a/core/java/android/widget/AdapterViewAnimator.java +++ b/core/java/android/widget/AdapterViewAnimator.java @@ -779,6 +779,15 @@ public abstract class AdapterViewAnimator extends AdapterView */ @android.view.RemotableViewMethod public void setRemoteViewsAdapter(Intent intent) { + // Ensure that we don't already have a RemoteViewsAdapter that is bound to an existing + // service handling the specified intent. + Intent.FilterComparison fc = new Intent.FilterComparison(intent); + if (mRemoteViewsAdapter != null && + fc.equals(mRemoteViewsAdapter.getRemoteViewsServiceIntent())) { + return; + } + + // Otherwise, create a new RemoteViewsAdapter for binding mRemoteViewsAdapter = new RemoteViewsAdapter(getContext(), intent, this); } diff --git a/core/java/android/widget/RemoteViewsAdapter.java b/core/java/android/widget/RemoteViewsAdapter.java index 70b9d59f73374..91b4afaa31c98 100644 --- a/core/java/android/widget/RemoteViewsAdapter.java +++ b/core/java/android/widget/RemoteViewsAdapter.java @@ -669,6 +669,9 @@ public class RemoteViewsAdapter extends BaseAdapter { public RemoteViewsAdapter(Context context, Intent intent, RemoteAdapterConnectionCallback callback) { mContext = context; mIntent = intent; + if (mIntent == null) { + throw new IllegalArgumentException("Non-null Intent must be specified."); + } // initialize the worker thread mWorkerThread = new HandlerThread("RemoteViewsCache-loader"); @@ -689,6 +692,10 @@ public class RemoteViewsAdapter extends BaseAdapter { unbindService(); } + public Intent getRemoteViewsServiceIntent() { + return mIntent; + } + public int getCount() { requestBindService(); return mViewCache.getCount(); diff --git a/core/java/android/widget/RemoteViewsService.java b/core/java/android/widget/RemoteViewsService.java index 584fa25f4145e..4548ff49e55a5 100644 --- a/core/java/android/widget/RemoteViewsService.java +++ b/core/java/android/widget/RemoteViewsService.java @@ -36,7 +36,7 @@ public abstract class RemoteViewsService extends Service { private static final String LOG_TAG = "RemoteViewsService"; // multimap implementation for reference counting - private HashMap> mRemoteViewFactories; + private HashMap> mRemoteViewFactories; private final Object mLock = new Object(); /** @@ -108,26 +108,28 @@ public abstract class RemoteViewsService extends Service { } public RemoteViewsService() { - mRemoteViewFactories = new HashMap>(); + mRemoteViewFactories = + new HashMap>(); } @Override public IBinder onBind(Intent intent) { synchronized (mLock) { // increment the reference count to the particular factory associated with this intent + Intent.FilterComparison fc = new Intent.FilterComparison(intent); Pair factoryRef = null; RemoteViewsFactory factory = null; - if (!mRemoteViewFactories.containsKey(intent)) { + if (!mRemoteViewFactories.containsKey(fc)) { factory = onGetViewFactory(intent); factoryRef = new Pair(factory, 1); - mRemoteViewFactories.put(intent, factoryRef); + mRemoteViewFactories.put(fc, factoryRef); factory.onCreate(); } else { - Pair oldFactoryRef = mRemoteViewFactories.get(intent); + Pair oldFactoryRef = mRemoteViewFactories.get(fc); factory = oldFactoryRef.first; int newRefCount = oldFactoryRef.second.intValue() + 1; factoryRef = new Pair(oldFactoryRef.first, newRefCount); - mRemoteViewFactories.put(intent, factoryRef); + mRemoteViewFactories.put(fc, factoryRef); } return new RemoteViewsFactoryAdapter(factory); } @@ -136,16 +138,19 @@ public abstract class RemoteViewsService extends Service { @Override public boolean onUnbind(Intent intent) { synchronized (mLock) { - if (mRemoteViewFactories.containsKey(intent)) { + Intent.FilterComparison fc = new Intent.FilterComparison(intent); + if (mRemoteViewFactories.containsKey(fc)) { // this alleviates the user's responsibility of having to clear all factories - Pair oldFactoryRef = mRemoteViewFactories.get(intent); + Pair oldFactoryRef = + mRemoteViewFactories.get(fc); int newRefCount = oldFactoryRef.second.intValue() - 1; if (newRefCount <= 0) { oldFactoryRef.first.onDestroy(); - mRemoteViewFactories.remove(intent); + mRemoteViewFactories.remove(fc); } else { - Pair factoryRef = new Pair(oldFactoryRef.first, newRefCount); - mRemoteViewFactories.put(intent, factoryRef); + Pair factoryRef = + new Pair(oldFactoryRef.first, newRefCount); + mRemoteViewFactories.put(fc, factoryRef); } } }