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就会发现[color=darkblue]04-29 02:32:20.612: INFO/ActivityThread(79): Publishing provider settings: com.android.providers.settings.SettingsProvider[/color]通过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);
}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值