ContentProvider是什么
ContentProvider是android四大组件之一。它为Android数据的存储和获取抽象了统一的接口,并通过Binder实现了进程间的通讯。对于Android中任何形式存在的数据,比如视频,音频,图片,通讯录,数据库等,如果想共享这些数据给其他应用或者同一个应用间共享,都可以通过ContentProvider来实现。
ContentProvider的使用
- 继承ContentProvider,并实现其抽象函数:Insert(),delete(),update(),query(),getType(),onCreate()。这六个函数,需要完成对共享数据的增删改查的功能。这些共享数据,可以是数据库,可以是文件或者其他数据。
//ContentProvider里面操作的共享数据常见的还是数据库
public class MyContentProvider extends ContentProvider{
@Nullable
@Override
public String getType(Uri uri) {
return null;
}
public MyContentProvider() {
super();
}
@Override
public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) {
return 0;
}
@Override
public int delete(Uri uri, String selection, String[] selectionArgs) {
return 0;
}
@Nullable
@Override
public Uri insert(Uri uri, ContentValues values) {
......
return uri;
}
@Nullable
@Override
public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) {
......
return null;
}
@Override
public boolean onCreate() {
......
return true;
}
}
- ContentProvider是Android四大组件之一,需要在AndroidManifest.xml中对其进行声明。如果需要跨进程使用,还需要设置权限。
//声明本应用 可允许通信的权限
<permission android:name="xxx" android:protectionLevel="normal"/>
<provider android:name="xxx"
android:authorities="xxx"
android:permission="xxx"
android:exported="true" />
android:exported: 设置此provider是否可以被其他进程使用
android:permission: 声明外界进程可访问该Provider的权限(读 & 写)
android:authorities:设置ContentProvider的唯一标识
- 通过Content.getContentResolver()获取ContentResolver对象,传入Uri并执行Insert(),delete(),update(),query(),getType()操作就可以访问ContentProvider中的五个函数。
Uri uri = Uri.parse("content://com.example.project:200/folder/subfolder/etc");
ContentResolver mContentResolver = getApplicationContext().getContentResolver();
ContentValues mContentValues = new ContentValues();
mContentValues.put(key,value);
mContentResolver.insert(uri,ContentValues);
三. ContentProvider的源码分析
https://blog.csdn.net/yueqian_scut/article/details/51338789
http://gityuan.com/2016/07/30/content-provider/
以上两篇博客讲解得比较全面了。
疑问点:
ContentProviderProxy这个代理对象是怎么获取的。
必须要反序列化createFromParcel()才会返回这个代理对象,但是找不到在哪里进行的反序列化。?????
ContentProviderHolder
public class ContentProviderHolder implements Parcelable {
public final ProviderInfo info;
public IContentProvider provider;
public IBinder connection;
public boolean noReleaseNeeded;
public ContentProviderHolder(ProviderInfo _info) {
info = _info;
}
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel dest, int flags) {
info.writeToParcel(dest, 0);
if (provider != null) {
dest.writeStrongBinder(provider.asBinder());
} else {
dest.writeStrongBinder(null);
}
dest.writeStrongBinder(connection);
dest.writeInt(noReleaseNeeded ? 1 : 0);
}
public static final Parcelable.Creator<ContentProviderHolder> CREATOR
= new Parcelable.Creator<ContentProviderHolder>() {
@Override
public ContentProviderHolder createFromParcel(Parcel source) {
return new ContentProviderHolder(source);
}
@Override
public ContentProviderHolder[] newArray(int size) {
return new ContentProviderHolder[size];
}
};
private ContentProviderHolder(Parcel source) {
info = ProviderInfo.CREATOR.createFromParcel(source);
provider = ContentProviderNative.asInterface(
source.readStrongBinder());
connection = source.readStrongBinder();
noReleaseNeeded = source.readInt() != 0;
}
}