Merge "Prevent multiple RemoteViewAdapters from being set for the same intent."
This commit is contained in:
@@ -4365,6 +4365,14 @@ public abstract class AbsListView extends AdapterView<ListAdapter> 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);
|
||||
}
|
||||
|
||||
|
||||
@@ -779,6 +779,15 @@ public abstract class AdapterViewAnimator extends AdapterView<Adapter>
|
||||
*/
|
||||
@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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -36,7 +36,7 @@ public abstract class RemoteViewsService extends Service {
|
||||
private static final String LOG_TAG = "RemoteViewsService";
|
||||
|
||||
// multimap implementation for reference counting
|
||||
private HashMap<Intent, Pair<RemoteViewsFactory, Integer>> mRemoteViewFactories;
|
||||
private HashMap<Intent.FilterComparison, Pair<RemoteViewsFactory, Integer>> mRemoteViewFactories;
|
||||
private final Object mLock = new Object();
|
||||
|
||||
/**
|
||||
@@ -108,26 +108,28 @@ public abstract class RemoteViewsService extends Service {
|
||||
}
|
||||
|
||||
public RemoteViewsService() {
|
||||
mRemoteViewFactories = new HashMap<Intent, Pair<RemoteViewsFactory, Integer>>();
|
||||
mRemoteViewFactories =
|
||||
new HashMap<Intent.FilterComparison, Pair<RemoteViewsFactory, Integer>>();
|
||||
}
|
||||
|
||||
@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<RemoteViewsFactory, Integer> factoryRef = null;
|
||||
RemoteViewsFactory factory = null;
|
||||
if (!mRemoteViewFactories.containsKey(intent)) {
|
||||
if (!mRemoteViewFactories.containsKey(fc)) {
|
||||
factory = onGetViewFactory(intent);
|
||||
factoryRef = new Pair<RemoteViewsFactory, Integer>(factory, 1);
|
||||
mRemoteViewFactories.put(intent, factoryRef);
|
||||
mRemoteViewFactories.put(fc, factoryRef);
|
||||
factory.onCreate();
|
||||
} else {
|
||||
Pair<RemoteViewsFactory, Integer> oldFactoryRef = mRemoteViewFactories.get(intent);
|
||||
Pair<RemoteViewsFactory, Integer> oldFactoryRef = mRemoteViewFactories.get(fc);
|
||||
factory = oldFactoryRef.first;
|
||||
int newRefCount = oldFactoryRef.second.intValue() + 1;
|
||||
factoryRef = new Pair<RemoteViewsFactory, Integer>(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<RemoteViewsFactory, Integer> oldFactoryRef = mRemoteViewFactories.get(intent);
|
||||
Pair<RemoteViewsFactory, Integer> oldFactoryRef =
|
||||
mRemoteViewFactories.get(fc);
|
||||
int newRefCount = oldFactoryRef.second.intValue() - 1;
|
||||
if (newRefCount <= 0) {
|
||||
oldFactoryRef.first.onDestroy();
|
||||
mRemoteViewFactories.remove(intent);
|
||||
mRemoteViewFactories.remove(fc);
|
||||
} else {
|
||||
Pair<RemoteViewsFactory, Integer> factoryRef = new Pair<RemoteViewsFactory, Integer>(oldFactoryRef.first, newRefCount);
|
||||
mRemoteViewFactories.put(intent, factoryRef);
|
||||
Pair<RemoteViewsFactory, Integer> factoryRef =
|
||||
new Pair<RemoteViewsFactory, Integer>(oldFactoryRef.first, newRefCount);
|
||||
mRemoteViewFactories.put(fc, factoryRef);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user