Chinaunix
标题:
ContentProvider分析
[打印本页]
作者:
aliounian
时间:
2011-12-21 08:41
标题:
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代码
Log.i(TAG,
"Starting System Content Providers."
);
ActivityManagerService.installSystemProviders();
Log.i(TAG, "Starting System Content Providers."); 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
.
}
欢迎光临 Chinaunix (http://bbs.chinaunix.net/)
Powered by Discuz! X3.2