ContentProvider分析

ContentProvider何时创建呢?这是一个值得深思的问题?
据我这两天的了解是在你要用到的时候才会调用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就会发现 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();
到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);
    }
}




你可能感兴趣的:(java,android,xml)