contentResolver与ContentProvider理解
来源:互联网 发布:架子鼓谱软件 编辑:程序博客网 时间:2024/05/12 04:33
注:
Application是一个完整的应用,比如某个apk,它对应一个Application,它里面可能包含n个Activity。
涉及到的类froyo/frameworks/base/core/java/android/app/ApplicationContext.java
froyo/frameworks/base/core/java/android/app/ActivityThread.java
froyo/frameworks/base/services/java/com/android/server/am/ActivityManagerService.java
当我们启动手机之后,如果需要启动一个activity,ActivityThread,ActivityManagerService就开始发挥作用了,这里不做细述。
当我们真正的启动一个activity的时候,我们会把当前Application的ApplicationContext传进去,
ApplicationContext实例持有一个mContextResolver对象,该对象对应于ApplicationContext的
内部类ApplicationContentResolver.
当activity调用getContentResolver()时,我们实际调用的是当前ApplicationContext中的mContextResolver.
由于黑色的继承关系,我们可以得到红色的调用关系
代码片段如下:
Activity调用ContextWrapper的方法
getContentResolver() {
mBase.getContentResolver();
}
然后会调用到ApplicationContext的方法
getContentResolver() {
return mContentResolver;
}
其中:
mContentResolve r = new ApplicationContentResolver(this, mainThread);
private static final class ApplicationContentResolver extends ContentResolver {
public ApplicationContentResolver(Context context,
ActivityThread mainThread)
{
super(context);
mMainThread = mainThread;
}
@Override
protected IContentProvider acquireProvider(Context context, String name)
{
return mMainThread.acquireProvider (context, name);
}
@Override
public boolean releaseProvider(IContentProvider provider)
{
return mMainThread.releaseProvider(provider);
}
private final ActivityThread mMainThread;
}
当执行mContentResolver.query()的时候,我们会调用父类ContentResolver的query();
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;
}
}
public final IContentProvider acquireProvider(Uri uri)
{
if (!SCHEME_CONTENT.equals(uri.getScheme())) {
return null;
}
String auth = uri.getAuthority();
if (auth != null) {
return acquireProvider(mContext, uri.getAuthority());
}
return null;
}
此时,会调用子类实例aquireProvider(Context,name);
mMainThread.acquireProvider (context, name);
实现为:
public final IContentProvider acquireProvider (Context c, String name) {
IContentProvider provider = getProvider (c, name);
if(provider == null)
return null;
IBinder jBinder = provider.asBinder(); //获得binder对象,跨进程传递数据。
synchronized(mProviderMap) {
ProviderRefCount prc = mProviderRefCountMap.get(jBinder);
if(prc == null) {
mProviderRefCountMap.put(jBinder, new ProviderRefCount(1));
} else {
prc.count++;
} //end else
} //end synchronized
return provider;
}
private final IContentProvider getProvider (Context context, String name) {
synchronized(mProviderMap) {
final ProviderRecord pr = mProviderMap .get(name); //ActivityThread中持有所有的Provider的实例
if (pr != null) {
return pr.mProvider;
}
}
//如果确实没有,则查找,并install,再没有就直接抛异常了。
IActivityManager.ContentProviderHolder holder = null;
try {
holder = ActivityManagerNative.getDefault().getContentProvider(
getApplicationThread(), name);
} catch (RemoteException ex) {
}
if (holder == null) {
Log.e(TAG, "Failed to find provider info for " + name);
return null;
}
if (holder.permissionFailure != null) {
throw new SecurityException("Permission " + holder.permissionFailure
+ " required for provider " + name);
}
IContentProvider prov = installProvider(context, holder.provider,
holder.info, true);
//Log.i(TAG, "noReleaseNeeded=" + holder.noReleaseNeeded);
if (holder.noReleaseNeeded || holder.provider == null) {
// We are not going to release the provider if it is an external
// provider that doesn't care about being released, or if it is
// a local provider running in this process.
//Log.i(TAG, "*** NO RELEASE NEEDED");
synchronized(mProviderMap) {
mProviderRefCountMap.put(prov.asBinder(), new ProviderRefCount(10000));
}
}
return prov;
}
到这里的话,ContentResovler与ContentProvider的关系就搞懂了,具体其他的细节,将分为不同的方面,分别讲述。
以下加入自己的理解:
首先在androidManinfest.xml注册provider,这样做是为了让系统底层调用继承contentprovider的子类。甚至contentprovider的onCreate方法也是系统底层调用的。这个方法可以调用SQLiteOpenHelper来创建数据库。
第二当在其他类中调用ContentResovler的时候,实际上间接是调用ContentProvider相应的方法。方法内在调用SQLiteOpenHelper来实现操作。但是中间加上ContentProvider这个作为隔离,导致一边修改数据库,同时读取数据库的时候可以达到线程安全。因为ContentProvider加了异步。具体看上面分析synchronized。
第三用到ContentProvider会设计多个操作类。
类层级关系:ContentResovler方法内调用ContentProvider-》SQLiteOpenHelper-》SQLiteDatabase
在ContentProvider这个层次就用到URI层次匹配了对数据库进行增删改查。而不用sql语句。会用到UriMatcher和Cursor类。
- contentResolver与ContentProvider理解
- ContentResolver + SqliteOpenHelper + ContentProvider 理解
- ContentProvider与ContentResolver使用
- ContentResolver与ContentProvider
- ContentProvider与ContentResolver使用
- ContentProvider与ContentResolver实例
- ContentProvider与ContentResolver使用
- ContentProvider与ContentResolver使用
- 王立平--ContentResolver与ContentProvider
- ContentProvider与ContentResolver
- ContentProvider与ContentResolver使用
- ContentProvider与ContentResolver使用
- ContentProvider与ContentResolver使用
- ContentProvider与ContentResolver使用
- ContentProvider与ContentResolver使用
- ContentProvider与ContentResolver使用
- ContentProvider与ContentResolver
- ContentResolver与ContentProvider
- Ubuntu防火墙设置
- 自定义readLine
- C语言中的malloc/free与C++中的new/delete的区别
- 利用java ,apache和android的方法来获取网络数据
- HPUOJ1293 考试排名
- contentResolver与ContentProvider理解
- 数据结构终结版总结----第一章 绪论
- LeetCode | #6 ZigZag Conversion
- 过滤器检验用户是否登录
- 484D - Kindergarten DP
- Java进程
- Eclipse中hibernate连接mySQL数据库练习
- [Telerik]RadDocking第02篇 保存和加载RadDocking的布局
- 基于openssl的计算机安全学demo(包含Diffie-Hellman,HAMC,AES的简单应用)