常用鏈接

          統計

          最新評論

          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 九寶 閱讀(1869) 評論(0)  編輯  收藏 所屬分類: android

          主站蜘蛛池模板: 涡阳县| 威宁| 靖安县| 化隆| 安丘市| 冀州市| 望谟县| 宣城市| 当阳市| 开阳县| 南部县| 贡嘎县| 读书| 法库县| 平定县| 策勒县| 永德县| 枞阳县| 黄浦区| 察隅县| 丹巴县| 德格县| 桦南县| 道孚县| 衡水市| 屯昌县| 湖州市| 余庆县| 时尚| 濮阳县| 定日县| 邯郸县| 南陵县| 莱芜市| 宾川县| 枣强县| 喀喇沁旗| 蚌埠市| 巴彦淖尔市| 宁津县| 五莲县|