ContentProvider何时创建呢?这是一个值得深思的问题?
据我这两天的了解是在你要用到的时候才会调用ContentProvider的onCreate函数进行创建。你就会什么时候叫要用到的时候呢?
比如你要查询或删除修改数据库的时候通过ContentResolver的quire或delete来操纵数据时就会调用ContentProvider
的onCreate函数,若已经创建了数据库就不会再次创建。可以通过ContentResolver的源码来理解
- 1. public final Cursor query(Uri uri, String[] projection,
-
2. String selection, String[] selectionArgs, String sortOrder) {
-
3. IContentProvider provider = acquireProvider(uri);
-
4. if (provider == null) {
-
5. return null;
-
6. }
-
7. try {
-
8. Cursor qCursor = provider.query(uri, projection, selection, selectionArgs, sortOrder);
-
9. if(qCursor == null) {
-
10. releaseProvider(provider);
-
11. return null;
-
12. }
-
13. //Wrap the cursor object into CursorWrapperInner object
-
14. return new CursorWrapperInner(qCursor, provider);
-
15. } catch (RemoteException e) {
-
16. releaseProvider(provider);
-
17. return null;
-
18. } catch(RuntimeException e) {
-
19. releaseProvider(provider);
-
20. throw e;
-
21. }
-
22. }
ContentResolver中的acquireProvider(uri)来获得对应的Provider.通过uri中的Authority
的字段知道是要用哪个provider.也就是为什么要在Provider的menifester.xml中
.
下面对android的几个已有的Provider的进行说明一下:
1,SettingsProvider
- 1. <!-- Permission to write Gservices in SettingsProvider -->
-
2. <permission android:name="android.permission.WRITE_GSERVICES"
-
3. android:label="@string/permlab_writeGservices"
-
4. android:description="@string/permdesc_writeGservices"
-
5. android:protectionLevel="signature" />
-
6.
-
7. <application android:allowClearUserData="false"
-
8. android:label="Settings Storage"
-
9. android:icon="@drawable/ic_launcher_settings">
-
10.
-
11. <provider android:name="SettingsProvider" android:authorities="settings"
-
12. android:process="system" android:multiprocess="false"
-
13. android:writePermission="android.permission.WRITE_SETTINGS"
-
14. android:initOrder="100" />
-
15. </application>
-
16. /manifest>
若你仔细查看SettingsProvider就会发现在它的manifester.xml中在android:process="system" 和android:sharedUserId="android.uid.system
package="com.android.providers.settings"
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中的- Log.i(TAG, "Starting System Content Providers.");
- ActivityManagerService.installSystemProviders();
Log.i(TAG, "Starting System Content Providers.");
ActivityManagerService.installSystemProviders();到ActivityManagerService.java中的
- 1. public static final void installSystemProviders() {
-
2. [color=blue]ProcessRecord app = mSelf.mProcessNames.get("system", Process.SYSTEM_UID);[/color]
-
3. List providers = mSelf.generateApplicationProvidersLocked(app);
-
4. mSystemThread.installSystemProviders(providers);
-
5. }
再到ActivityThread.java:
- 1. public final void installSystemProviders(List providers) {
-
2. if (providers != null) {
-
3. installContentProviders(mInitialApplication,
-
4. (List<ProviderInfo>)providers);
-
5. }
-
6. }
- 1. private final void installContentProviders(
-
2. Context context, List<ProviderInfo> providers) {
-
3. final ArrayList<IActivityManager.ContentProviderHolder> results =
-
4. new ArrayList<IActivityManager.ContentProviderHolder>();
-
5.
-
6. Iterator<ProviderInfo> i = providers.iterator();
-
7. while (i.hasNext()) {
-
8. ProviderInfo cpi = i.next();
-
9. StringBuilder buf = new StringBuilder(128);
-
10. buf.append("Publishing provider ");
-
11. buf.append(cpi.authority);
-
12. buf.append(": ");
-
13. buf.append(cpi.name);
-
14. Log.i(TAG, buf.toString());
-
15. IContentProvider cp = installProvider(context, null, cpi, false);
-
16. if (cp != null) {
-
17. IActivityManager.ContentProviderHolder cph =
-
18. new IActivityManager.ContentProviderHolder(cpi);
-
19. cph.provider = cp;
-
20. results.add(cph);
-
21. // Don't ever unload this provider from the process.
-
22. synchronized(mProviderMap) {
-
23. mProviderRefCountMap.put(cp.asBinder(), new ProviderRefCount(10000));
-
24. }
-
25. }
-
26. }
2,CalendarProvider
Manifester.xml
- 1. <receiver android:name="CalendarReceiver">
-
2. <intent-filter>
-
3. <action android:name="android.intent.action.BOOT_COMPLETED" />
-
4. </intent-filter>
-
5. </receiver> <provider android:name="CalendarProvider" android:authorities="calendar"
-
6. android:syncable="true" android:multiprocess="false"
-
7. android:readPermission="android.permission.READ_CALENDAR"
-
8. android:writePermission="android.permission.WRITE_CALENDAR" />
并不采用了SettingsProvider的方式而是通过了android.intent.action.BOOT_COMPLETED的方式:
CalendarReceiver.java
- 1. public class CalendarReceiver extends BroadcastReceiver {
-
2.
-
3. static final String SCHEDULE = "com.android.providers.calendar.SCHEDULE_ALARM";
-
4.
-
5. @Override
-
6. public void onReceive(Context context, Intent intent) {
-
7. String action = intent.getAction();
-
8. ContentResolver cr = context.getContentResolver();
-
9. CalendarProvider provider;
-
10. IContentProvider icp = cr.acquireProvider("calendar");
-
11. provider = (CalendarProvider) ContentProvider.
-
12. coerceToLocalContentProvider(icp);
-
13. if (action.equals(SCHEDULE)) {
-
14. provider.scheduleNextAlarm(false /* do not remove alarms */);
-
15. } else if (action.equals(Intent.ACTION_BOOT_COMPLETED)) {
-
16. provider.bootCompleted();
-
17. }
-
18. cr.releaseProvider(icp);
-
19. }
-
20. }
阅读(2264) | 评论(0) | 转发(1) |