Android ContentProvider的基本使用

今天我准备写一个android 软件版本升级功能,从网上发现了一个downloadmanager配合ContentProdiver下载更新的例子,由于ContentProvider在开发中很少自定义,所以忘了很多,并且自己没有ContentProvider的笔记帮助回忆,所以今天做了一个学习笔记。

大家对这个组件都不陌生,它的主要功能就是进程间通信。例如A应该要获得B应用的数据,就可以用ContentProvider来进行数据共享。android系统中也有很多使用ContentProvider的地方,例如,我们要获得通讯录中的用户信息就是通过ContentProvider实现的,只不过他是系统定义好的,我们直接使用而已。

ContentProvider的理解

contentProvider既然是进程间通信,那么肯定可以有两个应用(一个也是可以的)。假如,现在有两个应用A和B,B应用想获得A应用中的数据,该如何做呢?有点像问答题偷笑

第一个问题,在android系统中有很多应用,B应用如何精确的找到A应用?

第二个问题,假如B应用通过某种方式精确定位到A应用了,B应用如何获得A应用的数据呢?


解:为什么可以找到A,因为Android系统提供了一个Uri,通过Uri口可以找到A,Uri有三部分组成:

*content://: 这个是Android的ContentProvider规定的,就像上网的http://协议一样

*xx.xx.xx : 这个ContentProvider的authority部分,android系统就是通过这个东西来找到操作那个ContentProvider,只要访问特定的ContentProvider这个部分就是固定的,和上网协议的域名部分一样,这部分可以随便定义。例如,com.de.contentprovider,网络上的域名可以是www.baidu.com,他们没有区别。 

*data : 资源部分(或说数据部分相对于上网协议的资源路径),当访问者访问不同的资源,它是动态改变的。

需要指出的是,android 的uri所能表达的功能更丰富,它还可以支持如下的uri:

content://com.de.contentprovider/data/2

此时它要访问的资源是 data/2 ,data数据中id为2的记录。

其实我们可以把ContentProvider看成一个网站,ContentResolver(下面会说他的作用)看成浏览器,ContentResolver通过Uri找到特定的CnotentProvider,然后调用ContentProvider中的方法,然后返回给ContentResolver。就像浏览器访问服务器后服务器经过一些操作把数据给浏览器。


解:为什么B应用可以获得A应用中的数据,B应用要获得A应用中的数据要用到一个类,即ContentResolver,它可以找到ContentProvider,然后ContentProvider操作数据然后返回给ContentResolver。

ContentResolver c = context.getContentResolver(); 

ContentResolver中有什么方法可以用呢,操作数据组要就是“增删改查”,所以它对应的方法就是“增删改查”:

insert(Uir uri,ContentValues values);向uri对应的ContentProvider中插入数据

delete(Uri uri,String where,String[] selectionArgs);删除uri对应的ContentProvider中where匹配的数据。

update(...);

query(...);


从上面可以看出,ContentResolver和ContentProvider之间的关系就是委托关系,通过ContentResolver调用方法,它实际上调用的是ContentProvider中的方法,上面的4中方法ContentProvider中都一一对应,但是要用户自己实现。也可看成是远程调用,ContentResolver调用远程的ContentProvider中的方法


下面有个例子:

ContentResoler

package com.luo.downloadapk;

import android.content.ContentResolver;
import android.database.Cursor;
import android.net.Uri;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Toast;

import com.luo.downloadapk.text.MatcherUtils;

public class MainActivity extends AppCompatActivity {

    private  ContentResolver contentResolver;
    private Uri uri = Uri.parse("content://com.luo.text/");
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        initResolvers();
        findViewById(R.id.btnCheck).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                query();
            }
        });
    }

    private void initResolvers(){
         contentResolver = this.getContentResolver();
    }


    private void query(){
        //调用ContentResolver的query()方法
        //实际上返回的是该Uri对应的ContentProvider的query()方法的返回值
        Cursor cursor = contentResolver.query(uri,null,null,null,null);
        Toast.makeText(this,"远程ContentProvider返回的Cursor为:"+cursor,Toast.LENGTH_SHORT).show();
    }

}
通过
 Uri uri = Uri.parse("content://com.luo.text/");

找到对应的ContentProvider,下面是ContentProvider代码:

package com.luo.downloadapk.ContentProvideDemo;

import android.content.ContentProvider;
import android.content.ContentValues;
import android.database.Cursor;
import android.net.Uri;
import android.support.annotation.Nullable;

/**
 * Created by LawnLuo on 12/29/16.
 */

public class Demo1ContentProvide extends ContentProvider {

    //第一次创建该ContentProdiver时调用
    @Override
    public boolean onCreate() {
        System.out.println("---onCreate()----");
        return false;
    }

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

    //该方法返回值代表了该ContentProdiver所提供数据的MIME类型
    @Nullable
    @Override
    public String getType(Uri uri) {
        return null;
    }

    //实现插入方法,该方法应该返回插入的记录的Uri
    @Nullable
    @Override
    public Uri insert(Uri uri, ContentValues values) {
        return null;
    }

    //实现的删除方法该方法应该返回被删除的记录条数
    @Override
    public int delete(Uri uri, String selection, String[] selectionArgs) {
        return 0;
    }

    //实现跟新方法,该方法应该返回被的记录条数
    @Override
    public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) {
        return 0;
    }
}

需要注意的是在写完ContentProvider后要在Manifest.xml文件中注册一下,代码如下


<provider
    android:authorities="com.luo.text"
    android:name=".ContentProvideDemo.Demo1ContentProvide"
    android:exported="true"/><!--exported = true指定该ContentProvider可以在其他的应用中调用,反之则不能-->






评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值