一分钟学会Android--ContentProvider

在开发中,我们经常会调用系统联系人,系统相册,视频等。联系人,相册这些算是一个独立的应用,那我们自己的应用怎么能调用其他应用的数据呢?
这其实就是ContentProvider的功劳了,ContentProvider:Android四大组件之一,其作用相当于两个不同应用之前数据交互的桥梁,通过它可以实现跨应用数据共享。

实现步骤

第一步:被调用方提供操作数据的接口,通过继承ContentProvider并重写insert(),delete(),query(),update()完成增删查改的功能。
注意:这里的这几个方法看起来跟数据库的很像,但是这并不意味着数据源必须是数据库,也可以是文件,SharedPreference等,只是大部分数据源都是用的数据库而已。

第二步:被调用方在Manifest.xml文件中注册上一步实现的ContentProvider。

第三步:调用方通过ContentResolver用Uri与第一步创建的ContentProvider连接,并调用暴露出的方法实现数据交互。

下面用代码来说明ContentProvider的使用,顺便吐槽一句,好多人写博客,明明是讲这个,非要在里面揉一大推其他的东西,讲个ContentProvider,三分之二都是SqlLite的操作,除了篇幅多了还有什么卵用。

创建ContentProvider,都是需要重新的父类方法

public class MyContentProvider extends ContentProvider {

    @Override
    public boolean onCreate() {
        return false;
    }

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

    @Nullable
    @Override
    public String getType(Uri uri) {
        Log.v("out" , "getType方法执行了");
        return null;
    }

    @Nullable
    @Override
    public Uri insert(Uri uri, ContentValues values) {
        Log.v("out" , "Insert方法执行了");
        return uri;
    }

    @Override
    public int delete(Uri uri, String selection, String[] selectionArgs) {
        Log.v("out" , "getType方法执行了");
        return 0;
    }

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

在Manifest.xml中注册

<provider
            android:authorities="com.wangliang160616.androidtest.hello"
            android:name="com.wangliang160616.androidtest.others.MyContentProvider"
            android:exported="true"/>

* 创建一个Activity调用这个ContentProvider,为了实现跨进程调用,我们配置了这个Activity的process属性让它运行在另外一个进程中*

public class ContentProviderTestActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        int pid = android.os.Process.myPid();
        Log.v("out" , "新Activity的进程:"+pid);
        setContentView(R.layout.activity_content_provider_test);
        //创建ContentResolver对象
        ContentResolver contentResolver = getContentResolver();
        Uri uri = Uri.parse("content://"+"com.wangliang160616.androidtest.hello/a/b/10");
        ContentValues contentValues = new ContentValues();
        Uri returnUri = contentResolver.insert(uri , contentValues);
        Log.v("out" , "返回的uri:"+returnUri);
    }
}

看一下结果:
这里写图片描述

最后,还有一个技能点需要get,就是Uri的处理,上面我们将Uri传到了ContentProvider,拿到Uri后需要解析。

UriMatcher和ContentMatcher(下面的代码是网上扒来的,非原创)

uriMatcher用于匹配Uri

//常量UriMatcher.NO_MATCH表示不匹配任何路径的返回码
UriMatcher  sMatcher = new UriMatcher(UriMatcher.NO_MATCH);
//如果match()方法匹配content://com.bing.procvide.personprovider/person路径,返回匹配码为1
sMatcher.addURI("com.bing.procvide.personprovider", "person", 1);//添加需要匹配uri,如果匹配就会返回匹配码
//如果match()方法匹配content://com.bing.provider.personprovider/person/230路径,返回匹配码为2
sMatcher.addURI("com.bing.provider.personprovider", "person/#", 2);//#号为通配符
switch (sMatcher.match(Uri.parse("content://com.ljq.provider.personprovider/person/10"))) { 
   case 1
     break;
   case 2
     break;
   default://不匹配
     break;
}

ContentUris类用于操作Uri路径后面的ID部分:

Uri uri = Uri.parse("content://com.bing.provider.personprovider/person")
Uri resultUri = ContentUris.withAppendedId(uri, 10); 
//生成后的Uri为:content://com.bing.provider.personprovider/person/10
//parseId(uri)方法用于从路径中获取ID部分:
Uri uri = Uri.parse("content://com.ljq.provider.personprovider/person/10")
long personid = ContentUris.parseId(uri);//获取的结果为:10

补充:还有很重要的一点,数据变化和监听

设置监听也很简单,ContentResolver调用registerContentObserver()方法即可。

//注册监听
//这个true代表了只要是uri的派生出的Uri变化了也会通知
        contentResolver.registerContentObserver(uri, true, new ContentObserver(null) {
        //onChange还有一个更多参数的重载方法,但是没什么用,还是调用的这个方法,所以只需要重写这个就可以了
            @Override
            public void onChange(boolean selfChange) {
                super.onChange(selfChange);
                Log.v("out" , "我知道你变了");
            }
        });

然后在数据变化的地方开启通知:

getContext().getContentResolver().notifyChange(uri , null);
好了,ContentProvider就是这么简单,告诉我,是不是分分钟掌握。至于增删查改的具体操作,随你了…
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值