1499cb9f516062b654952d282f211bee44c31a3c2Winson Chung/* 2499cb9f516062b654952d282f211bee44c31a3c2Winson Chung * Copyright (C) 2007 The Android Open Source Project 3499cb9f516062b654952d282f211bee44c31a3c2Winson Chung * 4499cb9f516062b654952d282f211bee44c31a3c2Winson Chung * Licensed under the Apache License, Version 2.0 (the "License"); 5499cb9f516062b654952d282f211bee44c31a3c2Winson Chung * you may not use this file except in compliance with the License. 6499cb9f516062b654952d282f211bee44c31a3c2Winson Chung * You may obtain a copy of the License at 7499cb9f516062b654952d282f211bee44c31a3c2Winson Chung * 8499cb9f516062b654952d282f211bee44c31a3c2Winson Chung * http://www.apache.org/licenses/LICENSE-2.0 9499cb9f516062b654952d282f211bee44c31a3c2Winson Chung * 10499cb9f516062b654952d282f211bee44c31a3c2Winson Chung * Unless required by applicable law or agreed to in writing, software 11499cb9f516062b654952d282f211bee44c31a3c2Winson Chung * distributed under the License is distributed on an "AS IS" BASIS, 12499cb9f516062b654952d282f211bee44c31a3c2Winson Chung * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13499cb9f516062b654952d282f211bee44c31a3c2Winson Chung * See the License for the specific language governing permissions and 14499cb9f516062b654952d282f211bee44c31a3c2Winson Chung * limitations under the License. 15499cb9f516062b654952d282f211bee44c31a3c2Winson Chung */ 16499cb9f516062b654952d282f211bee44c31a3c2Winson Chung 17499cb9f516062b654952d282f211bee44c31a3c2Winson Chungpackage android.widget; 18499cb9f516062b654952d282f211bee44c31a3c2Winson Chung 19499cb9f516062b654952d282f211bee44c31a3c2Winson Chungimport java.util.HashMap; 20499cb9f516062b654952d282f211bee44c31a3c2Winson Chung 21499cb9f516062b654952d282f211bee44c31a3c2Winson Chungimport android.app.Service; 22499cb9f516062b654952d282f211bee44c31a3c2Winson Chungimport android.content.Intent; 23499cb9f516062b654952d282f211bee44c31a3c2Winson Chungimport android.os.IBinder; 24499cb9f516062b654952d282f211bee44c31a3c2Winson Chung 25499cb9f516062b654952d282f211bee44c31a3c2Winson Chungimport com.android.internal.widget.IRemoteViewsFactory; 26499cb9f516062b654952d282f211bee44c31a3c2Winson Chung 27499cb9f516062b654952d282f211bee44c31a3c2Winson Chung/** 28499cb9f516062b654952d282f211bee44c31a3c2Winson Chung * The service to be connected to for a remote adapter to request RemoteViews. Users should 29499cb9f516062b654952d282f211bee44c31a3c2Winson Chung * extend the RemoteViewsService to provide the appropriate RemoteViewsFactory's used to 30499cb9f516062b654952d282f211bee44c31a3c2Winson Chung * populate the remote collection view (ListView, GridView, etc). 31499cb9f516062b654952d282f211bee44c31a3c2Winson Chung */ 32499cb9f516062b654952d282f211bee44c31a3c2Winson Chungpublic abstract class RemoteViewsService extends Service { 33499cb9f516062b654952d282f211bee44c31a3c2Winson Chung 34499cb9f516062b654952d282f211bee44c31a3c2Winson Chung private static final String LOG_TAG = "RemoteViewsService"; 35499cb9f516062b654952d282f211bee44c31a3c2Winson Chung 3616c8d8a558f94ec14ef52bb5ac11044e2d0d902cWinson Chung // Used for reference counting of RemoteViewsFactories 3716c8d8a558f94ec14ef52bb5ac11044e2d0d902cWinson Chung // Because we are now unbinding when we are not using the Service (to allow them to be 3816c8d8a558f94ec14ef52bb5ac11044e2d0d902cWinson Chung // reclaimed), the references to the factories that are created need to be stored and used when 3916c8d8a558f94ec14ef52bb5ac11044e2d0d902cWinson Chung // the service is restarted (in response to user input for example). When the process is 4016c8d8a558f94ec14ef52bb5ac11044e2d0d902cWinson Chung // destroyed, so is this static cache of RemoteViewsFactories. 4184bbb020217adcdfe0694c44ccab57e208ffde16Winson Chung private static final HashMap<Intent.FilterComparison, RemoteViewsFactory> sRemoteViewFactories = 4216c8d8a558f94ec14ef52bb5ac11044e2d0d902cWinson Chung new HashMap<Intent.FilterComparison, RemoteViewsFactory>(); 4384bbb020217adcdfe0694c44ccab57e208ffde16Winson Chung private static final Object sLock = new Object(); 44499cb9f516062b654952d282f211bee44c31a3c2Winson Chung 45499cb9f516062b654952d282f211bee44c31a3c2Winson Chung /** 46499cb9f516062b654952d282f211bee44c31a3c2Winson Chung * An interface for an adapter between a remote collection view (ListView, GridView, etc) and 47499cb9f516062b654952d282f211bee44c31a3c2Winson Chung * the underlying data for that view. The implementor is responsible for making a RemoteView 480e2de6d7187ef67ec00a2f2544450caa4a239c39Adam Cohen * for each item in the data set. This interface is a thin wrapper around {@link Adapter}. 496394c0e52cf641d93f678fd052499aa952e3595dWinson Chung * 506394c0e52cf641d93f678fd052499aa952e3595dWinson Chung * @see android.widget.Adapter 516eceb00db916e2435a1625af631623bf95ae0e7fWinson Chung * @see android.appwidget.AppWidgetManager 52499cb9f516062b654952d282f211bee44c31a3c2Winson Chung */ 53499cb9f516062b654952d282f211bee44c31a3c2Winson Chung public interface RemoteViewsFactory { 546394c0e52cf641d93f678fd052499aa952e3595dWinson Chung /** 556394c0e52cf641d93f678fd052499aa952e3595dWinson Chung * Called when your factory is first constructed. The same factory may be shared across 566394c0e52cf641d93f678fd052499aa952e3595dWinson Chung * multiple RemoteViewAdapters depending on the intent passed. 576394c0e52cf641d93f678fd052499aa952e3595dWinson Chung */ 58499cb9f516062b654952d282f211bee44c31a3c2Winson Chung public void onCreate(); 590e2de6d7187ef67ec00a2f2544450caa4a239c39Adam Cohen 606394c0e52cf641d93f678fd052499aa952e3595dWinson Chung /** 616eceb00db916e2435a1625af631623bf95ae0e7fWinson Chung * Called when notifyDataSetChanged() is triggered on the remote adapter. This allows a 626eceb00db916e2435a1625af631623bf95ae0e7fWinson Chung * RemoteViewsFactory to respond to data changes by updating any internal references. 636eceb00db916e2435a1625af631623bf95ae0e7fWinson Chung * 640e2de6d7187ef67ec00a2f2544450caa4a239c39Adam Cohen * Note: expensive tasks can be safely performed synchronously within this method. In the 650e2de6d7187ef67ec00a2f2544450caa4a239c39Adam Cohen * interim, the old data will be displayed within the widget. 660e2de6d7187ef67ec00a2f2544450caa4a239c39Adam Cohen * 676eceb00db916e2435a1625af631623bf95ae0e7fWinson Chung * @see android.appwidget.AppWidgetManager#notifyAppWidgetViewDataChanged(int[], int) 686394c0e52cf641d93f678fd052499aa952e3595dWinson Chung */ 696394c0e52cf641d93f678fd052499aa952e3595dWinson Chung public void onDataSetChanged(); 700e2de6d7187ef67ec00a2f2544450caa4a239c39Adam Cohen 716394c0e52cf641d93f678fd052499aa952e3595dWinson Chung /** 726394c0e52cf641d93f678fd052499aa952e3595dWinson Chung * Called when the last RemoteViewsAdapter that is associated with this factory is 736394c0e52cf641d93f678fd052499aa952e3595dWinson Chung * unbound. 746394c0e52cf641d93f678fd052499aa952e3595dWinson Chung */ 75499cb9f516062b654952d282f211bee44c31a3c2Winson Chung public void onDestroy(); 76499cb9f516062b654952d282f211bee44c31a3c2Winson Chung 770e2de6d7187ef67ec00a2f2544450caa4a239c39Adam Cohen /** 780e2de6d7187ef67ec00a2f2544450caa4a239c39Adam Cohen * See {@link Adapter#getCount()} 790e2de6d7187ef67ec00a2f2544450caa4a239c39Adam Cohen * 800e2de6d7187ef67ec00a2f2544450caa4a239c39Adam Cohen * @return Count of items. 810e2de6d7187ef67ec00a2f2544450caa4a239c39Adam Cohen */ 82499cb9f516062b654952d282f211bee44c31a3c2Winson Chung public int getCount(); 830e2de6d7187ef67ec00a2f2544450caa4a239c39Adam Cohen 840e2de6d7187ef67ec00a2f2544450caa4a239c39Adam Cohen /** 850e2de6d7187ef67ec00a2f2544450caa4a239c39Adam Cohen * See {@link Adapter#getView(int, android.view.View, android.view.ViewGroup)}. 860e2de6d7187ef67ec00a2f2544450caa4a239c39Adam Cohen * 870e2de6d7187ef67ec00a2f2544450caa4a239c39Adam Cohen * Note: expensive tasks can be safely performed synchronously within this method, and a 880e2de6d7187ef67ec00a2f2544450caa4a239c39Adam Cohen * loading view will be displayed in the interim. See {@link #getLoadingView()}. 890e2de6d7187ef67ec00a2f2544450caa4a239c39Adam Cohen * 900e2de6d7187ef67ec00a2f2544450caa4a239c39Adam Cohen * @param position The position of the item within the Factory's data set of the item whose 910e2de6d7187ef67ec00a2f2544450caa4a239c39Adam Cohen * view we want. 920e2de6d7187ef67ec00a2f2544450caa4a239c39Adam Cohen * @return A RemoteViews object corresponding to the data at the specified position. 930e2de6d7187ef67ec00a2f2544450caa4a239c39Adam Cohen */ 94499cb9f516062b654952d282f211bee44c31a3c2Winson Chung public RemoteViews getViewAt(int position); 950e2de6d7187ef67ec00a2f2544450caa4a239c39Adam Cohen 960e2de6d7187ef67ec00a2f2544450caa4a239c39Adam Cohen /** 970e2de6d7187ef67ec00a2f2544450caa4a239c39Adam Cohen * This allows for the use of a custom loading view which appears between the time that 980e2de6d7187ef67ec00a2f2544450caa4a239c39Adam Cohen * {@link #getViewAt(int)} is called and returns. If null is returned, a default loading 990e2de6d7187ef67ec00a2f2544450caa4a239c39Adam Cohen * view will be used. 1000e2de6d7187ef67ec00a2f2544450caa4a239c39Adam Cohen * 1010e2de6d7187ef67ec00a2f2544450caa4a239c39Adam Cohen * @return The RemoteViews representing the desired loading view. 1020e2de6d7187ef67ec00a2f2544450caa4a239c39Adam Cohen */ 103499cb9f516062b654952d282f211bee44c31a3c2Winson Chung public RemoteViews getLoadingView(); 1040e2de6d7187ef67ec00a2f2544450caa4a239c39Adam Cohen 1050e2de6d7187ef67ec00a2f2544450caa4a239c39Adam Cohen /** 1060e2de6d7187ef67ec00a2f2544450caa4a239c39Adam Cohen * See {@link Adapter#getViewTypeCount()}. 1070e2de6d7187ef67ec00a2f2544450caa4a239c39Adam Cohen * 1080e2de6d7187ef67ec00a2f2544450caa4a239c39Adam Cohen * @return The number of types of Views that will be returned by this factory. 1090e2de6d7187ef67ec00a2f2544450caa4a239c39Adam Cohen */ 110499cb9f516062b654952d282f211bee44c31a3c2Winson Chung public int getViewTypeCount(); 1110e2de6d7187ef67ec00a2f2544450caa4a239c39Adam Cohen 1120e2de6d7187ef67ec00a2f2544450caa4a239c39Adam Cohen /** 1130e2de6d7187ef67ec00a2f2544450caa4a239c39Adam Cohen * See {@link Adapter#getItemId(int)}. 1140e2de6d7187ef67ec00a2f2544450caa4a239c39Adam Cohen * 1150e2de6d7187ef67ec00a2f2544450caa4a239c39Adam Cohen * @param position The position of the item within the data set whose row id we want. 1160e2de6d7187ef67ec00a2f2544450caa4a239c39Adam Cohen * @return The id of the item at the specified position. 1170e2de6d7187ef67ec00a2f2544450caa4a239c39Adam Cohen */ 118499cb9f516062b654952d282f211bee44c31a3c2Winson Chung public long getItemId(int position); 1190e2de6d7187ef67ec00a2f2544450caa4a239c39Adam Cohen 1200e2de6d7187ef67ec00a2f2544450caa4a239c39Adam Cohen /** 1210e2de6d7187ef67ec00a2f2544450caa4a239c39Adam Cohen * See {@link Adapter#hasStableIds()}. 1220e2de6d7187ef67ec00a2f2544450caa4a239c39Adam Cohen * 1230e2de6d7187ef67ec00a2f2544450caa4a239c39Adam Cohen * @return True if the same id always refers to the same object. 1240e2de6d7187ef67ec00a2f2544450caa4a239c39Adam Cohen */ 125499cb9f516062b654952d282f211bee44c31a3c2Winson Chung public boolean hasStableIds(); 126499cb9f516062b654952d282f211bee44c31a3c2Winson Chung } 127499cb9f516062b654952d282f211bee44c31a3c2Winson Chung 128499cb9f516062b654952d282f211bee44c31a3c2Winson Chung /** 129499cb9f516062b654952d282f211bee44c31a3c2Winson Chung * A private proxy class for the private IRemoteViewsFactory interface through the 130499cb9f516062b654952d282f211bee44c31a3c2Winson Chung * public RemoteViewsFactory interface. 131499cb9f516062b654952d282f211bee44c31a3c2Winson Chung */ 13216c8d8a558f94ec14ef52bb5ac11044e2d0d902cWinson Chung private static class RemoteViewsFactoryAdapter extends IRemoteViewsFactory.Stub { 13316c8d8a558f94ec14ef52bb5ac11044e2d0d902cWinson Chung public RemoteViewsFactoryAdapter(RemoteViewsFactory factory, boolean isCreated) { 134499cb9f516062b654952d282f211bee44c31a3c2Winson Chung mFactory = factory; 13516c8d8a558f94ec14ef52bb5ac11044e2d0d902cWinson Chung mIsCreated = isCreated; 13616c8d8a558f94ec14ef52bb5ac11044e2d0d902cWinson Chung } 13716c8d8a558f94ec14ef52bb5ac11044e2d0d902cWinson Chung public synchronized boolean isCreated() { 13816c8d8a558f94ec14ef52bb5ac11044e2d0d902cWinson Chung return mIsCreated; 139499cb9f516062b654952d282f211bee44c31a3c2Winson Chung } 140f58a96152cecb480decf8c0352b01322663e5cbcWinson Chung public synchronized void onDataSetChanged() { 1412625feae79ab418355c2a4dafe8b162bba3cc1cfAdam Cohen try { 1422625feae79ab418355c2a4dafe8b162bba3cc1cfAdam Cohen mFactory.onDataSetChanged(); 1432625feae79ab418355c2a4dafe8b162bba3cc1cfAdam Cohen } catch (Exception ex) { 1442625feae79ab418355c2a4dafe8b162bba3cc1cfAdam Cohen Thread t = Thread.currentThread(); 1452625feae79ab418355c2a4dafe8b162bba3cc1cfAdam Cohen Thread.getDefaultUncaughtExceptionHandler().uncaughtException(t, ex); 1462625feae79ab418355c2a4dafe8b162bba3cc1cfAdam Cohen } 1476394c0e52cf641d93f678fd052499aa952e3595dWinson Chung } 148c3f581b0474a216938810885f4f606e0db1f21ffWinson Chung public synchronized void onDataSetChangedAsync() { 149c3f581b0474a216938810885f4f606e0db1f21ffWinson Chung onDataSetChanged(); 150c3f581b0474a216938810885f4f606e0db1f21ffWinson Chung } 151f58a96152cecb480decf8c0352b01322663e5cbcWinson Chung public synchronized int getCount() { 1522625feae79ab418355c2a4dafe8b162bba3cc1cfAdam Cohen int count = 0; 1532625feae79ab418355c2a4dafe8b162bba3cc1cfAdam Cohen try { 1542625feae79ab418355c2a4dafe8b162bba3cc1cfAdam Cohen count = mFactory.getCount(); 1552625feae79ab418355c2a4dafe8b162bba3cc1cfAdam Cohen } catch (Exception ex) { 1562625feae79ab418355c2a4dafe8b162bba3cc1cfAdam Cohen Thread t = Thread.currentThread(); 1572625feae79ab418355c2a4dafe8b162bba3cc1cfAdam Cohen Thread.getDefaultUncaughtExceptionHandler().uncaughtException(t, ex); 1582625feae79ab418355c2a4dafe8b162bba3cc1cfAdam Cohen } 1592625feae79ab418355c2a4dafe8b162bba3cc1cfAdam Cohen return count; 160499cb9f516062b654952d282f211bee44c31a3c2Winson Chung } 161f58a96152cecb480decf8c0352b01322663e5cbcWinson Chung public synchronized RemoteViews getViewAt(int position) { 1622625feae79ab418355c2a4dafe8b162bba3cc1cfAdam Cohen RemoteViews rv = null; 1632625feae79ab418355c2a4dafe8b162bba3cc1cfAdam Cohen try { 1642625feae79ab418355c2a4dafe8b162bba3cc1cfAdam Cohen rv = mFactory.getViewAt(position); 1652625feae79ab418355c2a4dafe8b162bba3cc1cfAdam Cohen if (rv != null) { 1662625feae79ab418355c2a4dafe8b162bba3cc1cfAdam Cohen rv.setIsWidgetCollectionChild(true); 1672625feae79ab418355c2a4dafe8b162bba3cc1cfAdam Cohen } 1682625feae79ab418355c2a4dafe8b162bba3cc1cfAdam Cohen } catch (Exception ex) { 1692625feae79ab418355c2a4dafe8b162bba3cc1cfAdam Cohen Thread t = Thread.currentThread(); 1702625feae79ab418355c2a4dafe8b162bba3cc1cfAdam Cohen Thread.getDefaultUncaughtExceptionHandler().uncaughtException(t, ex); 1712625feae79ab418355c2a4dafe8b162bba3cc1cfAdam Cohen } 172ca6fd847945464c2ddddcd165021082c048f05fbAdam Cohen return rv; 173499cb9f516062b654952d282f211bee44c31a3c2Winson Chung } 174f58a96152cecb480decf8c0352b01322663e5cbcWinson Chung public synchronized RemoteViews getLoadingView() { 1752625feae79ab418355c2a4dafe8b162bba3cc1cfAdam Cohen RemoteViews rv = null; 1762625feae79ab418355c2a4dafe8b162bba3cc1cfAdam Cohen try { 1772625feae79ab418355c2a4dafe8b162bba3cc1cfAdam Cohen rv = mFactory.getLoadingView(); 1782625feae79ab418355c2a4dafe8b162bba3cc1cfAdam Cohen } catch (Exception ex) { 1792625feae79ab418355c2a4dafe8b162bba3cc1cfAdam Cohen Thread t = Thread.currentThread(); 1802625feae79ab418355c2a4dafe8b162bba3cc1cfAdam Cohen Thread.getDefaultUncaughtExceptionHandler().uncaughtException(t, ex); 1812625feae79ab418355c2a4dafe8b162bba3cc1cfAdam Cohen } 1822625feae79ab418355c2a4dafe8b162bba3cc1cfAdam Cohen return rv; 183499cb9f516062b654952d282f211bee44c31a3c2Winson Chung } 184f58a96152cecb480decf8c0352b01322663e5cbcWinson Chung public synchronized int getViewTypeCount() { 1852625feae79ab418355c2a4dafe8b162bba3cc1cfAdam Cohen int count = 0; 1862625feae79ab418355c2a4dafe8b162bba3cc1cfAdam Cohen try { 1872625feae79ab418355c2a4dafe8b162bba3cc1cfAdam Cohen count = mFactory.getViewTypeCount(); 1882625feae79ab418355c2a4dafe8b162bba3cc1cfAdam Cohen } catch (Exception ex) { 1892625feae79ab418355c2a4dafe8b162bba3cc1cfAdam Cohen Thread t = Thread.currentThread(); 1902625feae79ab418355c2a4dafe8b162bba3cc1cfAdam Cohen Thread.getDefaultUncaughtExceptionHandler().uncaughtException(t, ex); 1912625feae79ab418355c2a4dafe8b162bba3cc1cfAdam Cohen } 1922625feae79ab418355c2a4dafe8b162bba3cc1cfAdam Cohen return count; 193499cb9f516062b654952d282f211bee44c31a3c2Winson Chung } 194f58a96152cecb480decf8c0352b01322663e5cbcWinson Chung public synchronized long getItemId(int position) { 1952625feae79ab418355c2a4dafe8b162bba3cc1cfAdam Cohen long id = 0; 1962625feae79ab418355c2a4dafe8b162bba3cc1cfAdam Cohen try { 1972625feae79ab418355c2a4dafe8b162bba3cc1cfAdam Cohen id = mFactory.getItemId(position); 1982625feae79ab418355c2a4dafe8b162bba3cc1cfAdam Cohen } catch (Exception ex) { 1992625feae79ab418355c2a4dafe8b162bba3cc1cfAdam Cohen Thread t = Thread.currentThread(); 2002625feae79ab418355c2a4dafe8b162bba3cc1cfAdam Cohen Thread.getDefaultUncaughtExceptionHandler().uncaughtException(t, ex); 2012625feae79ab418355c2a4dafe8b162bba3cc1cfAdam Cohen } 2022625feae79ab418355c2a4dafe8b162bba3cc1cfAdam Cohen return id; 203499cb9f516062b654952d282f211bee44c31a3c2Winson Chung } 204f58a96152cecb480decf8c0352b01322663e5cbcWinson Chung public synchronized boolean hasStableIds() { 2052625feae79ab418355c2a4dafe8b162bba3cc1cfAdam Cohen boolean hasStableIds = false; 2062625feae79ab418355c2a4dafe8b162bba3cc1cfAdam Cohen try { 2072625feae79ab418355c2a4dafe8b162bba3cc1cfAdam Cohen hasStableIds = mFactory.hasStableIds(); 2082625feae79ab418355c2a4dafe8b162bba3cc1cfAdam Cohen } catch (Exception ex) { 2092625feae79ab418355c2a4dafe8b162bba3cc1cfAdam Cohen Thread t = Thread.currentThread(); 2102625feae79ab418355c2a4dafe8b162bba3cc1cfAdam Cohen Thread.getDefaultUncaughtExceptionHandler().uncaughtException(t, ex); 2112625feae79ab418355c2a4dafe8b162bba3cc1cfAdam Cohen } 2122625feae79ab418355c2a4dafe8b162bba3cc1cfAdam Cohen return hasStableIds; 213499cb9f516062b654952d282f211bee44c31a3c2Winson Chung } 21484bbb020217adcdfe0694c44ccab57e208ffde16Winson Chung public void onDestroy(Intent intent) { 21584bbb020217adcdfe0694c44ccab57e208ffde16Winson Chung synchronized (sLock) { 21684bbb020217adcdfe0694c44ccab57e208ffde16Winson Chung Intent.FilterComparison fc = new Intent.FilterComparison(intent); 21784bbb020217adcdfe0694c44ccab57e208ffde16Winson Chung if (RemoteViewsService.sRemoteViewFactories.containsKey(fc)) { 21884bbb020217adcdfe0694c44ccab57e208ffde16Winson Chung RemoteViewsFactory factory = RemoteViewsService.sRemoteViewFactories.get(fc); 2192625feae79ab418355c2a4dafe8b162bba3cc1cfAdam Cohen try { 2202625feae79ab418355c2a4dafe8b162bba3cc1cfAdam Cohen factory.onDestroy(); 2212625feae79ab418355c2a4dafe8b162bba3cc1cfAdam Cohen } catch (Exception ex) { 2222625feae79ab418355c2a4dafe8b162bba3cc1cfAdam Cohen Thread t = Thread.currentThread(); 2232625feae79ab418355c2a4dafe8b162bba3cc1cfAdam Cohen Thread.getDefaultUncaughtExceptionHandler().uncaughtException(t, ex); 2242625feae79ab418355c2a4dafe8b162bba3cc1cfAdam Cohen } 22584bbb020217adcdfe0694c44ccab57e208ffde16Winson Chung RemoteViewsService.sRemoteViewFactories.remove(fc); 22684bbb020217adcdfe0694c44ccab57e208ffde16Winson Chung } 22784bbb020217adcdfe0694c44ccab57e208ffde16Winson Chung } 22884bbb020217adcdfe0694c44ccab57e208ffde16Winson Chung } 229499cb9f516062b654952d282f211bee44c31a3c2Winson Chung 230499cb9f516062b654952d282f211bee44c31a3c2Winson Chung private RemoteViewsFactory mFactory; 23116c8d8a558f94ec14ef52bb5ac11044e2d0d902cWinson Chung private boolean mIsCreated; 232499cb9f516062b654952d282f211bee44c31a3c2Winson Chung } 233499cb9f516062b654952d282f211bee44c31a3c2Winson Chung 234499cb9f516062b654952d282f211bee44c31a3c2Winson Chung @Override 235499cb9f516062b654952d282f211bee44c31a3c2Winson Chung public IBinder onBind(Intent intent) { 23684bbb020217adcdfe0694c44ccab57e208ffde16Winson Chung synchronized (sLock) { 2379b3a2cf2a0a482ce8212eb2775176dd4c23e8e9aWinson Chung Intent.FilterComparison fc = new Intent.FilterComparison(intent); 238499cb9f516062b654952d282f211bee44c31a3c2Winson Chung RemoteViewsFactory factory = null; 23916c8d8a558f94ec14ef52bb5ac11044e2d0d902cWinson Chung boolean isCreated = false; 24084bbb020217adcdfe0694c44ccab57e208ffde16Winson Chung if (!sRemoteViewFactories.containsKey(fc)) { 241499cb9f516062b654952d282f211bee44c31a3c2Winson Chung factory = onGetViewFactory(intent); 24284bbb020217adcdfe0694c44ccab57e208ffde16Winson Chung sRemoteViewFactories.put(fc, factory); 243499cb9f516062b654952d282f211bee44c31a3c2Winson Chung factory.onCreate(); 24416c8d8a558f94ec14ef52bb5ac11044e2d0d902cWinson Chung isCreated = false; 245499cb9f516062b654952d282f211bee44c31a3c2Winson Chung } else { 24684bbb020217adcdfe0694c44ccab57e208ffde16Winson Chung factory = sRemoteViewFactories.get(fc); 24716c8d8a558f94ec14ef52bb5ac11044e2d0d902cWinson Chung isCreated = true; 248499cb9f516062b654952d282f211bee44c31a3c2Winson Chung } 24916c8d8a558f94ec14ef52bb5ac11044e2d0d902cWinson Chung return new RemoteViewsFactoryAdapter(factory, isCreated); 250499cb9f516062b654952d282f211bee44c31a3c2Winson Chung } 251499cb9f516062b654952d282f211bee44c31a3c2Winson Chung } 252499cb9f516062b654952d282f211bee44c31a3c2Winson Chung 253499cb9f516062b654952d282f211bee44c31a3c2Winson Chung /** 254499cb9f516062b654952d282f211bee44c31a3c2Winson Chung * To be implemented by the derived service to generate appropriate factories for 255499cb9f516062b654952d282f211bee44c31a3c2Winson Chung * the data. 256499cb9f516062b654952d282f211bee44c31a3c2Winson Chung */ 257499cb9f516062b654952d282f211bee44c31a3c2Winson Chung public abstract RemoteViewsFactory onGetViewFactory(Intent intent); 258499cb9f516062b654952d282f211bee44c31a3c2Winson Chung} 259