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的关系就搞懂了,具体其他的细节,将分为不同的方面,分别讲述。
分享到:
相关推荐
此为ContentResolver与ContentProvider的使用Demo.
主要介绍了android之ContentResolver与ContentProvider介绍,需要的朋友可以参考下
android 自定义 ContentProvider 以及 ContentResolver
简单实现数据库操作,能对外共享数据,ContentProvider和ContentResolver,实现数据对外共享
ContentProvider和ContentResolver永远是相对的,本章主要是讲ContentResolver的使用,当然是在android系统提供ContentProvider的情况下。 ContentProvider与ContentResolver概念上的东西的就不讲了,主要讲一下...
安卓程序间数据共享的实现,包含两个程序,共享资源的程序和读取资源的程序,共享资源的程序包含了SQLite数据库的使用。
ContentProvider与ContentResolver 与 SQLiteOpenHelper http://blog.csdn.net/i_do_can/article/details/50937380 http://blog.csdn.net/i_do_can/article/details/50937380
自定义ContentProvider的流程 ContentResolver访问通讯录数据库
主要介绍了Android ContentResolver使用说明,需要的朋友可以参考下
主要介绍了Android中ContentProvider和ContentResolver详解的相关资料,需要的朋友可以参考下
Android应用程序之间数据共享ContentResolver.pdf
Android中ContentResolver的使用说明.pdf 学习资料 复习资料 教学资源
程序例子包含了2个独立的Android程序,其中一个负责提供数据并提供本地操作,另外一个可以跨进程访问提供者提供的数据。例子虽然简单,但是覆盖到了Content Provider里面的知识点,例如集成Content Provider,Uri的...
利用ContentResolver访问者获取手机短信信息,在此记录一下,一遍以后查询。 首先看一下结果,结果如下: activity_message.xml类: <LinearLayout xmlns:android=http://schemas.android.com/apk/res/android...
之前在用到ContentProvider时也是在网上找的教程,但是按照那些做法不怎么全面,我是没有实现出来,并且对于报错也没有给出解释原因与解决办法,也是通过借鉴与自己摸索,将自己 的一点想法分享出来。包含 ...
利用contentprovider和ContentResolver获取手机联系人信息
ContentProvider使用简介里面的demo
http://blog.csdn.net/i_do_can/article/details/50942221 http://blog.csdn.net/i_do_can/article/details/50942221 http://blog.csdn.net/i_do_can/article/details/50942221