ContentProvider原理分析

前景知识:对于ContentProvider理解必须对IBinder有所了解(一个提供跨进程信息交换的一个工具),会ContentProvider的简单使用。本文是基于你已经具备以上知识点阅读

1.名词解释

为了方便讲解定义几个名词
Provider:ContentProvider内容提供端
Client:通过URL获取信息端

2.ContentProvider简单介绍

Provider提供端继承ContentProvider 实现query,insert等方法

public class NameProvider extends ContentProvider {
@Override
public boolean onCreate() {
    return false;
}

@Nullable
@Override
public Cursor query(@NonNull Uri uri, @Nullable String[] projection, @Nullable String selection, @Nullable String[] selectionArgs, @Nullable String sortOrder) {
    return null;
}

@Nullable
@Override
public String getType(@NonNull Uri uri) {
    return null;
}

@Nullable
@Override
public Uri insert(@NonNull Uri uri, @Nullable ContentValues values) {
    return null;
}

@Override
public int delete(@NonNull Uri uri, @Nullable String selection, @Nullable String[] selectionArgs) {
    return 0;
}

@Override
public int update(@NonNull Uri uri, @Nullable ContentValues values, @Nullable String selection, @Nullable String[] selectionArgs) {
    return 0;
}
}

Client端使用

//获得cursor,得到内容
Cursor nameCursor = getContentResolver().query(nameUri, new String[]{"_id", "name"}, null, null, null);

ContentProvider的使用还是非常的简单方便的。

3.核心结论

  1. ContentProvider是通过IBinder实现通信过程的
  2. getContentResolver获得到的是ApplicationContentResolver(在ContextImpt中实现的)
  3. Client端ApplicationContentResolver使用ContentProviderProxy作为IBinder的Proxy(ContentProviderNative中实现)
  4. Provider端通过Transport作为IBinder的实现端(ContentProvider中实现)
getContentResolve->ApplicationContentResolver->ContentProviderProxy<===IBidner====>Transport->NameProvider

4. 源码分析

下面我们按照getContentResolver().query(nameUri, new String[]{"_id", "name"}, null, null, null);熟悉一下上面过程
getContentResolver()得到的ApplicationContentResolver 这个过程在Client 的Application创建的时候就已经存在了


ContextImpl中创建的ApplicationContentResolver

在获取IContentProvider 用了三个方法,类似我们图片缓存机制一样
IContentProvider unstableProvider = acquireUnstableProvider(uri);
unstableProviderDied(unstableProvider);
stableProvider = acquireProvider(uri);
这里我们只关注 acquireProvider(uri);



我们在ApplicationContentResolver找到下面
acquireProvider.png

我们在ActivityThread.java中找到

ActivityManagerNative.getDefault()也是通过IBinder机制通信的,其实他真正是ActivityManagerProxy与之通信的是ActivityManagerService.java(在System Service进程中运行),ApplicationContentResolver 去获得ContentProviderProxy本身也是跨进程通信,client端和System service通信,从System service中获得到ContentProviderProxy
下面是在ActivityManagerService.java中getContentProvider的实现


getContentProvider.png

getContentProviderImpl中内容可以参看checkTime中的注释
getContentProviderImpl.PNG

5.注意事项

  1. 在Android 系统会在启动提供程序时调用 onCreate()。您只应在此方法中执行运行快速的初始化任务,并将数据库创建和数据加载推迟到提供程序实际收到数据请求时进行。 如果您在 onCreate() 中执行长时间的任务,则会减慢提供程序的启动速度, 进而减慢提供程序对其他应用的响应速度。
    当Provider没有启动,在Client调用Provider是先执行Provider的onCreate再调用Provider Application onCreate方法,所以不要在Provider中做太多初始化工作,特别是其中的初始化工作要依赖Application onCreate会让程序不稳的,甚至Crash
    Provider没有启动.png

6. 补充及参考

源码是基于Android 6.0
源码分析https://blog.csdn.net/u010961631/article/details/14227421
Android ContentProviderhttps://developer.android.com/reference/android/content/ContentProvider.html

你可能感兴趣的:(ContentProvider原理分析)