`
javacode23
  • 浏览: 29278 次
  • 性别: Icon_minigender_1
  • 来自: 北京
最近访客 更多访客>>
社区版块
存档分类
最新评论

android contentResolver与contentProvider如何关联在一起的

阅读更多

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的关系就搞懂了,具体其他的细节,将分为不同的方面,分别讲述。
分享到:
评论

相关推荐

    Android+Room+ContentProvider

    在Android应用开发中,数据持久化是一个至关重要的环节,而Android Room和ContentProvider是其中的两个关键组件。本文将深入探讨这两个技术,并结合实际案例,解释如何在Android应用中使用它们来管理和共享SQLite...

    ContentProvider短信的获取备份

    ContentQuery将与ContentResolver的query方法一起使用,以获取满足特定条件的短信数据。 接下来,我们需要解析返回的Cursor对象,它包含了所有查询到的短信记录。每条短信记录通常包括id、thread_id(对话ID)、...

    ContentProviderSQLiteDemo1.zip

    ContentProviderSQLiteDemo1.zip文件中的示例项目,就是将这两者巧妙地结合在一起,为我们展示了如何通过ContentProvider来操作SQLite数据库。接下来,我们将深入探讨这两个关键组件以及它们在实际应用中的结合。 ...

    LoadSQLiteManager:用异步加载数据库(LoaderManager,ContentProvider,ContentResolver,SQLiteOpenHelper)

    `ContentResolver`是Android组件(如Activity或Service)用来与ContentProvider交互的接口。它不直接操作数据库,而是通过发送请求给ContentProvider来获取或修改数据。在`LoadSQLiteManager`中,ContentResolver是...

    android_contect.rar_ mapViewActivity_android

    至于`android通讯录程序`,这可能是一个实现了基本联系人操作(添加、删除、更新)的应用示例,它展示了如何使用Android的ContactContract类和ContentResolver来与系统联系人数据库进行交互。开发者可以使用`...

    Android ContenProvider学习

    ContentResolver是与ContentProvider交互的接口,它位于应用程序层,负责调用ContentProvider的方法进行数据操作。 对于工具性的使用,开发者可以利用Android Studio的Android Plugin for Gradle,生成...

    查询联系人

    ListView是Android SDK中用于显示大量数据列表的视图组件,通常与Adapter一起使用,Adapter将数据集转换为ListView可显示的视图。在这个项目中,ListView可能被用来显示联系人的姓名、电话号码等关键信息,每个条目...

    Android4.4 settings源码

    在源码中,我们可以看到如何通过 `ContentResolver` 与 ContentProvider 进行交互,读取或修改系统设置值。 5. **BroadcastReceiver**: Settings 应用常会注册 BroadcastReceiver 监听系统广播,以便在特定事件...

    【eoeAndroid特刊】第十五期:Android多媒体

    2. Content Provider:通过ContentResolver和ContentProvider,应用可以跨进程共享多媒体数据,实现资源的集成和统一管理。 六、多媒体文件存储 1. 外部存储:Android应用可以使用外部存储(SD卡)来存储多媒体...

    Android源码——完整的通讯录项目源码.zip

    开发者可以通过ContentResolver和ContentProvider接口与之交互,进行增删改查操作。 5. **CursorLoader和LoaderManager**:Loader机制用于异步加载数据,避免阻塞UI线程。在通讯录应用中,CursorLoader用于查询...

    android图书管理系统完整demo

    ContentResolver是应用程序与ContentProvider交互的桥梁,通过它,我们可以执行增删查改的操作。 图书的展示通常会用到ListView或RecyclerView组件,它们可以动态加载和显示列表数据。适配器(Adapter)是这两个...

    LoaderManager查询联系人与图片

    ContentResolver是应用程序与ContentProvider进行交互的接口,而ContentProvider则是Android系统中数据共享的机制,它可以让我们访问系统服务(如联系人、短信等)的数据。使用ContentResolver调用query()方法,配合...

    关于sqlite

    开发者可以通过Android的ContentResolver和ContentProvider接口与数据库交互,实现数据的CRUD(创建、读取、更新、删除)操作。 总之,SQLite是Android开发中的关键组件,用于存储和管理应用数据。通过深入理解和...

    android notePad solution 源码

    【标题】:“Android NotePad Solution 源码分析” 在这个教程中,我们将深入探讨一个名为“NotePad”的Android应用程序的源代码。...此外,它也展示了如何将这些组件有效地整合在一起,以实现一个完整功能的应用。

    精品(2021-2022年)资料达内Android全真模块实训.docx

    封装将数据和行为绑定在一起。 - **访问修饰符**:如public、private控制成员的访问权限。 - **static和final关键字**:static用于声明类变量或方法,final用于声明不可变的变量或方法。 - **方法重写和多态**:子类...

    android架构-复习基本OOP知识a

    例如,ContentProvider通过ContentResolver接口与其他组件交互,实现数据共享。 8. 泛型:泛型允许在编译时指定类型参数,增强了代码的类型安全性和效率。在Android开发中,集合类如List、Map等常使用泛型,确保...

    Android开发指南中文版-----应用程序框架

    Android应用的用户界面由多个视图(Views)组成,这些视图组织在一起形成视图层次结构(View Hierarchy)。 ##### 视图层次(View Hierarchy) 视图层次结构描述了视图如何组织在一起,形成了用户界面的结构。 ##### ...

    android demo

    它允许用户通过左右滑动来切换不同的页面,通常与PagerAdapter一起使用,PagerAdapter负责管理页面的创建和销毁,以优化内存使用。 2. **ListView**:ListView是Android中用来展示大量数据的滚动视图,适合于显示...

    Android技术面试资料整理

    - **FrameLayout(框架布局)**:是最简单的布局,它会按照添加顺序将所有子视图堆叠在一起,后面添加的视图会覆盖前面的视图。这种布局适用于只需要在一个位置放置一个视图的情况。 - **LinearLayout(线性布局)*...

    安卓读取手机短信代码

    首先,我们需要知道在安卓中,数据通常是通过ContentProvider进行访问的。ContentProvider是安卓系统提供的一种接口,它允许应用程序之间共享数据。短信数据存储在系统的SMS表中,我们可以使用ContentResolver来查询...

Global site tag (gtag.js) - Google Analytics