Chinaunix首页 | 论坛 | 博客
  • 博客访问: 292939
  • 博文数量: 68
  • 博客积分: 1474
  • 博客等级: 上尉
  • 技术积分: 616
  • 用 户 组: 普通用户
  • 注册时间: 2011-02-12 12:07
文章分类

全部博文(68)

文章存档

2011年(68)

分类: 嵌入式

2011-05-11 14:46:53

ContentProvider何时创建呢?这是一个值得深思的问题?
据我这两天的了解是在你要用到的时候才会调用ContentProvider的onCreate函数进行创建。你就会什么时候叫要用到的时候呢? 比如你要查询或删除修改数据库的时候通过ContentResolver的quire或delete来操纵数据时就会调用ContentProvider 的onCreate函数,若已经创建了数据库就不会再次创建。可以通过ContentResolver的源码来理解
Java代码  收藏代码

  1. 1. public final Cursor query(Uri uri, String[] projection,
  2.    2. String selection, String[] selectionArgs, String sortOrder) {
  3.    3. IContentProvider provider = acquireProvider(uri);
  4.    4. if (provider == null) {
  5.    5. return null;
  6.    6. }
  7.    7. try {
  8.    8. Cursor qCursor = provider.query(uri, projection, selection, selectionArgs, sortOrder);
  9.    9. if(qCursor == null) {
  10.   10. releaseProvider(provider);
  11.   11. return null;
  12.   12. }
  13.   13. //Wrap the cursor object into CursorWrapperInner object
  14.   14. return new CursorWrapperInner(qCursor, provider);
  15.   15. } catch (RemoteException e) {
  16.   16. releaseProvider(provider);
  17.   17. return null;
  18.   18. } catch(RuntimeException e) {
  19.   19. releaseProvider(provider);
  20.   20. throw e;
  21.   21. }
  22.   22. }

ContentResolver中的acquireProvider(uri)来获得对应的Provider.通过uri中的Authority 的字段知道是要用哪个provider.也就是为什么要在Provider的menifester.xml中.


下面对android的几个已有的Provider的进行说明一下:
1,SettingsProvider
Java代码  收藏代码

  1. 1. <!-- Permission to write Gservices in SettingsProvider -->
  2.    2. <permission android:name="android.permission.WRITE_GSERVICES"
  3.    3. android:label="@string/permlab_writeGservices"
  4.    4. android:description="@string/permdesc_writeGservices"
  5.    5. android:protectionLevel="signature" />
  6.    6.
  7.    7. <application android:allowClearUserData="false"
  8.    8. android:label="Settings Storage"
  9.    9. android:icon="@drawable/ic_launcher_settings">
  10.   10.
  11.   11. <provider android:name="SettingsProvider" android:authorities="settings"
  12.   12. android:process="system" android:multiprocess="false"
  13.   13. android:writePermission="android.permission.WRITE_SETTINGS"
  14.   14. android:initOrder="100" />
  15.   15. </application>
  16.   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中的
Java代码  收藏代码
  1. Log.i(TAG, "Starting System Content Providers.");  
  2.  ActivityManagerService.installSystemProviders();  
Log.i(TAG, "Starting System Content Providers."); ActivityManagerService.installSystemProviders();到ActivityManagerService.java中的
Java代码  收藏代码

  1. 1. public static final void installSystemProviders() {
  2.    2. [color=blue]ProcessRecord app = mSelf.mProcessNames.get("system", Process.SYSTEM_UID);[/color]
  3.    3. List providers = mSelf.generateApplicationProvidersLocked(app);
  4.    4. mSystemThread.installSystemProviders(providers);
  5.    5. }
                  
再到ActivityThread.java:
Java代码  收藏代码

  1. 1. public final void installSystemProviders(List providers) {
  2.    2. if (providers != null) {
  3.    3. installContentProviders(mInitialApplication,
  4.    4. (List<ProviderInfo>)providers);
  5.    5. }
  6.    6. }
Java代码  收藏代码

  1. 1. private final void installContentProviders(
  2.    2. Context context, List<ProviderInfo> providers) {
  3.    3. final ArrayList<IActivityManager.ContentProviderHolder> results =
  4.    4. new ArrayList<IActivityManager.ContentProviderHolder>();
  5.    5.
  6.    6. Iterator<ProviderInfo> i = providers.iterator();
  7.    7. while (i.hasNext()) {
  8.    8. ProviderInfo cpi = i.next();
  9.    9. StringBuilder buf = new StringBuilder(128);
  10.   10. buf.append("Publishing provider ");
  11.   11. buf.append(cpi.authority);
  12.   12. buf.append(": ");
  13.   13. buf.append(cpi.name);
  14.   14. Log.i(TAG, buf.toString());
  15.   15. IContentProvider cp = installProvider(context, null, cpi, false);
  16.   16. if (cp != null) {
  17.   17. IActivityManager.ContentProviderHolder cph =
  18.   18. new IActivityManager.ContentProviderHolder(cpi);
  19.   19. cph.provider = cp;
  20.   20. results.add(cph);
  21.   21. // Don't ever unload this provider from the process.
  22.   22. synchronized(mProviderMap) {
  23.   23. mProviderRefCountMap.put(cp.asBinder(), new ProviderRefCount(10000));
  24.   24. }
  25.   25. }
  26.   26. }


2,CalendarProvider
Manifester.xml
Java代码  收藏代码

  1. 1. <receiver android:name="CalendarReceiver">
  2.    2. <intent-filter>
  3.    3. <action android:name="android.intent.action.BOOT_COMPLETED" />
  4.    4. </intent-filter>
  5.    5. </receiver> <provider android:name="CalendarProvider" android:authorities="calendar"
  6.    6. android:syncable="true" android:multiprocess="false"
  7.    7. android:readPermission="android.permission.READ_CALENDAR"
  8.    8. android:writePermission="android.permission.WRITE_CALENDAR" />


并不采用了SettingsProvider的方式而是通过了android.intent.action.BOOT_COMPLETED的方式:
CalendarReceiver.java
Java代码  收藏代码

  1. 1. public class CalendarReceiver extends BroadcastReceiver {
  2.    2.
  3.    3. static final String SCHEDULE = "com.android.providers.calendar.SCHEDULE_ALARM";
  4.    4.
  5.    5. @Override
  6.    6. public void onReceive(Context context, Intent intent) {
  7.    7. String action = intent.getAction();
  8.    8. ContentResolver cr = context.getContentResolver();
  9.    9. CalendarProvider provider;
  10.   10. IContentProvider icp = cr.acquireProvider("calendar");
  11.   11. provider = (CalendarProvider) ContentProvider.
  12.   12. coerceToLocalContentProvider(icp);
  13.   13. if (action.equals(SCHEDULE)) {
  14.   14. provider.scheduleNextAlarm(false /* do not remove alarms */);
  15.   15. } else if (action.equals(Intent.ACTION_BOOT_COMPLETED)) {
  16.   16. provider.bootCompleted();
  17.   17. }
  18.   18. cr.releaseProvider(icp);
  19.   19. }
  20.   20. }

阅读(2264) | 评论(0) | 转发(1) |
给主人留下些什么吧!~~