常用链接

统计

最新评论

ContentProvider分析

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


下面对android的几个已有的Provider的进行说明一下: 
1,SettingsProvider
Java代码 
  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 
<manifest xmlns:android="http://schemas.android.com/apk/res/android" 
        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();  
到ActivityManagerService.java中的
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:
Java代码 
  1. public final void installSystemProviders(List providers) {  
  2.         if (providers != null) {  
  3.             installContentProviders(mInitialApplication,  
  4.                                     (List<ProviderInfo>)providers);  
  5.         }  
  6.     }  
Java代码 
  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 
Java代码 
  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 
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. }  

posted on 2011-02-18 14:51 九宝 阅读(1856) 评论(0)  编辑  收藏 所属分类: android


只有注册用户登录后才能发表评论。


网站导航: