ContentProvider何时创建呢?这是一个值得深思的问题?
据我这两天的了解是在你要用到的时候才会调用ContentProvider的onCreate函数进行创建。你就会什么时候叫要用到的时候呢?比如你要查询或删除修改数据库的时候通过ContentResolver的quire或delete来操纵数据时就会调用ContentProvider的onCreate函数,若已经创建了数据库就不会再次创建。可以通过ContentResolver的源码来理解
ContentResolver中的acquireProvider(uri)来获得对应的Provider.通过uri中的Authority的字段知道是要用哪个provider.也就是为什么要在Provider的menifester.xml中<provider.. android:authority="">.
下面对android的几个已有的Provider的进行说明一下:
1,SettingsProvider
若你仔细查看SettingsProvider就会发现在它的manifester.xml中在android:process="system" 和android:sharedUserId="android.uid.system
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.android.providers.settings"
android:sharedUserId="android.uid.system">,我猜测它就是多了这两条语句使得系统加载完就加载它。若你注意开机的logcat就会发现[color=darkblue]04-29 02:32:20.612: INFO/ActivityThread(79): Publishing provider settings: com.android.providers.settings.SettingsProvider[/color]通过ActivityThread开始往上追你就会发现
从SystemServer.java中的
再到ActivityThread.java:
2,CalendarProvider
Manifester.xml
并不采用了SettingsProvider的方式而是通过了android.intent.action.BOOT_COMPLETED的方式:
CalendarReceiver.java
据我这两天的了解是在你要用到的时候才会调用ContentProvider的onCreate函数进行创建。你就会什么时候叫要用到的时候呢?比如你要查询或删除修改数据库的时候通过ContentResolver的quire或delete来操纵数据时就会调用ContentProvider的onCreate函数,若已经创建了数据库就不会再次创建。可以通过ContentResolver的源码来理解
public final Cursor query(Uri uri, String[] projection,
String selection, String[] selectionArgs, String sortOrder) {
IContentProvider provider = acquireProvider(uri);
if (provider == null) {
return null;
}
try {
Cursor qCursor = provider.query(uri, projection, selection, selectionArgs, sortOrder);
if(qCursor == null) {
releaseProvider(provider);
return null;
}
//Wrap the cursor object into CursorWrapperInner object
return new CursorWrapperInner(qCursor, provider);
} catch (RemoteException e) {
releaseProvider(provider);
return null;
} catch(RuntimeException e) {
releaseProvider(provider);
throw e;
}
}
ContentResolver中的acquireProvider(uri)来获得对应的Provider.通过uri中的Authority的字段知道是要用哪个provider.也就是为什么要在Provider的menifester.xml中<provider.. android:authority="">.
下面对android的几个已有的Provider的进行说明一下:
1,SettingsProvider
<!-- Permission to write Gservices in SettingsProvider -->
<permission android:name="android.permission.WRITE_GSERVICES"
android:label="@string/permlab_writeGservices"
android:description="@string/permdesc_writeGservices"
android:protectionLevel="signature" />
<application android:allowClearUserData="false"
android:label="Settings Storage"
android:icon="@drawable/ic_launcher_settings">
<provider android:name="SettingsProvider" android:authorities="settings"
android:process="system" android:multiprocess="false"
android:writePermission="android.permission.WRITE_SETTINGS"
android:initOrder="100" />
</application>
</manifest>
若你仔细查看SettingsProvider就会发现在它的manifester.xml中在android:process="system" 和android:sharedUserId="android.uid.system
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.android.providers.settings"
android:sharedUserId="android.uid.system">,我猜测它就是多了这两条语句使得系统加载完就加载它。若你注意开机的logcat就会发现[color=darkblue]04-29 02:32:20.612: INFO/ActivityThread(79): Publishing provider settings: com.android.providers.settings.SettingsProvider[/color]通过ActivityThread开始往上追你就会发现
从SystemServer.java中的
Log.i(TAG, "Starting System Content Providers.");
ActivityManagerService.installSystemProviders();
到ActivityManagerService.java中的
public static final void installSystemProviders() {
[color=blue]ProcessRecord app = mSelf.mProcessNames.get("system", Process.SYSTEM_UID);[/color]
List providers = mSelf.generateApplicationProvidersLocked(app);
mSystemThread.installSystemProviders(providers);
}
再到ActivityThread.java:
public final void installSystemProviders(List providers) {
if (providers != null) {
installContentProviders(mInitialApplication,
(List<ProviderInfo>)providers);
}
}
private final void installContentProviders(
Context context, List<ProviderInfo> providers) {
final ArrayList<IActivityManager.ContentProviderHolder> results =
new ArrayList<IActivityManager.ContentProviderHolder>();
Iterator<ProviderInfo> i = providers.iterator();
while (i.hasNext()) {
ProviderInfo cpi = i.next();
StringBuilder buf = new StringBuilder(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 =
new IActivityManager.ContentProviderHolder(cpi);
cph.provider = cp;
results.add(cph);
// Don't ever unload this provider from the process.
synchronized(mProviderMap) {
mProviderRefCountMap.put(cp.asBinder(), new ProviderRefCount(10000));
}
}
}
2,CalendarProvider
Manifester.xml
<receiver android:name="CalendarReceiver">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver> <provider android:name="CalendarProvider" android:authorities="calendar"
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
public class CalendarReceiver extends BroadcastReceiver {
static final String SCHEDULE = "com.android.providers.calendar.SCHEDULE_ALARM";
@Override
public void onReceive(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 */);
} else if (action.equals(Intent.ACTION_BOOT_COMPLETED)) {
provider.bootCompleted();
}
cr.releaseProvider(icp);
}
}