ContentProvider何时创建呢?这是一个值得深思的问题?据我这两天的了解是在你要用到的时候才会调用ContentProvider的onCreate函数进行创建。你就会什么时候叫要用到的时候呢?比如你要查询或删除修改数据库的时候通过ContentResolver的quire或delete来操纵数据时就会调用ContentProvider的onCreate函数,若已经创建了数据库就不会再次创建。可以通过ContentResolver的源码来理解
Java代码
publicfinalCursor query(Uri uri, String[] projection,
String selection, String[] selectionArgs, String sortOrder) {
IContentProvider provider = acquireProvider(uri);
if(provider ==null) {
returnnull;
}
try{
Cursor qCursor = provider.query(uri, projection, selection, selectionArgs, sortOrder);
if(qCursor ==null) {
releaseProvider(provider);
returnnull;
}
//Wrap the cursor object into CursorWrapperInner object
returnnewCursorWrapperInner(qCursor, provider);
} catch(RemoteException e) {
releaseProvider(provider);
returnnull;
} catch(RuntimeException e) {
releaseProvider(provider);
throwe;
}
}
ContentResolver中的acquireProvider(uri)来获得对应的Provider.通过uri中的Authority的字段知道是要用哪个provider.也就是为什么要在Provider的menifester.xml中.下面对android的几个已有的Provider的进行说明一下:1,SettingsProvider
Java代码
android:label="@string/permlab_writeGservices"
android:description="@string/permdesc_writeGservices"
android:protectionLevel="signature"/>
android:label="Settings Storage"
android:icon="@drawable/ic_launcher_settings">
android:process="system"android:multiprocess="false"
android:writePermission="android.permission.WRITE_SETTINGS"
android:initOrder="100"/>
/manifest>
若你仔细查看SettingsProvider就会发现在它的manifester.xml中在android:process="system" 和android:sharedUserId="android.uid.system,我猜测它就是多了这两条语句使得系统加载完就加载它。若你注意开机的logcat就会发现04-29 02:32:20.612: INFO/ActivityThread(79): Publishing provider settings: com.android.providers.settings.SettingsProvider通过ActivityThread开始往上追你就会发现从SystemServer.java中的
Java代码
Log.i(TAG,"Starting System Content Providers.");
ActivityManagerService.installSystemProviders();
到ActivityManagerService.java中的
Java代码
publicstaticfinalvoidinstallSystemProviders() {
[color=blue]ProcessRecord app = mSelf.mProcessNames.get("system", Process.SYSTEM_UID);[/color]
List providers = mSelf.generateApplicationProvidersLocked(app);
mSystemThread.installSystemProviders(providers);
}
再到ActivityThread.java:
Java代码
publicfinalvoidinstallSystemProviders(List providers) {
if(providers !=null) {
installContentProviders(mInitialApplication,
(List)providers);
}
}
Java代码
privatefinalvoidinstallContentProviders(
Context context, List providers) {
finalArrayList results =
newArrayList();
Iterator i = providers.iterator();
while(i.hasNext()) {
ProviderInfo cpi = i.next();
StringBuilder buf = newStringBuilder(128);
buf.append("Publishing provider ");
buf.append(cpi.authority);
buf.append(": ");
buf.append(cpi.name);
Log.i(TAG, buf.toString());
IContentProvider cp = installProvider(context, null, cpi,false);
if(cp !=null) {
IActivityManager.ContentProviderHolder cph =
newIActivityManager.ContentProviderHolder(cpi);
cph.provider = cp;
results.add(cph);
// Don't ever unload this provider from the process.
synchronized(mProviderMap) {
mProviderRefCountMap.put(cp.asBinder(), newProviderRefCount(10000));
}
}
}
2,CalendarProviderManifester.xml
Java代码
android:syncable="true"android:multiprocess="false"
android:readPermission="android.permission.READ_CALENDAR"
android:writePermission="android.permission.WRITE_CALENDAR"/>
并不采用了SettingsProvider的方式而是通过了android.intent.action.BOOT_COMPLETED的方式:CalendarReceiver.java
Java代码
publicclassCalendarReceiverextendsBroadcastReceiver {
staticfinalString SCHEDULE ="com.android.providers.calendar.SCHEDULE_ALARM";
@Override
publicvoidonReceive(Context context, Intent intent) {
String action = intent.getAction();
ContentResolver cr = context.getContentResolver();
CalendarProvider provider;
IContentProvider icp = cr.acquireProvider("calendar");
provider = (CalendarProvider) ContentProvider.
coerceToLocalContentProvider(icp);
if(action.equals(SCHEDULE)) {
provider.scheduleNextAlarm(false/* do not remove alarms */);
} elseif(action.equals(Intent.ACTION_BOOT_COMPLETED)) {
provider.bootCompleted();
}
cr.releaseProvider(icp);
}
}
posted on 2011-02-18 14:51 九宝 阅读(1767) 评论(0) 编辑 收藏 所属分类: android