• 赵雅智_ContentProvider


    ContentProvider介绍

    ContentProvider是不同应用程序之间进行交换数据的标志API

    也就是说:一个应用程序通过ContentProvider暴露自己的数据操作接口,那么无论该应用是否启动(一定部署),其它应用程序能够通过该接口来操作该应用的内部数据,包含添加数据,删除数据,改动数据。查询数据等。


    当应用继承ContentProvider类,并重写该类用于提供数据和存储数据的方法,就能够向其它应用共享其数据。

    尽管使用其它方法也能够对外共享数据,但数据訪问方式会因数据存储的方式而不同

    如:採用文件方式对外共享数据,须要进行文件操作读写数据。

    採用sharedpreferences共享数据。须要使用sharedpreferences API读写数据。

    而使用ContentProvider共享数据的优点是统一了数据訪问方式


    通过ContentProvider对外共享数据步骤:

    继承ContentProvider并重写以下方法

    public class PersonContentProvider extends ContentProvider{

    public boolean onCreate()

    public Uri insert(Uri uri, ContentValues values)

    public int delete(Uri uri, String selection, String[] selectionArgs)

    public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs)

    public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder)

    public String getType(Uri uri)

    }

    方法介绍

    public boolean onCreate()

    在UserContentProvider创建之后,就会被调用,当其它应用程序第一次訪问contentPrivider时。该ContentProvider就会被创建出来

    public String getType(Uri uri)

    返回操作的类型 假设操作多条记录那么MINE类型vnd.android.cursor.dir/开头

    假设操作的数据仅仅有一条记录那么MINE类型vnd.android.cursor.item/开头

    public Uri insert(Uri uri, ContentValues values)

    插入操作

    public int delete(Uri uri, String selection, String[] selectionArgs)

    删除操作

    public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs)

    改动操作

    public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder)

    查询操作



    在AndroidManifest.xml使用<provider>对该ContentProvider进行配置

    为了能让其它应用找到该ContentProvider 。 ContentProvider 採用了authorities(主机名/域名)对它进行唯一标识,你能够把 ContentProvider看作是一个站点(想想,站点也是提供数据者),authorities 就是他的域名:

    <manifest .... >
        <application android:icon="@drawable/icon" android:label="@string/app_name">
            <provider android:name=".PersonContentProvider" android:authorities="cn.itcast.provider.personprovider"/>
        </application>
    </manifest>

    注意:一旦应用继承了ContentProvider类,后面我们就会把这个应用称为ContentProvider(内容提供者)。

    Uri介绍

    Uri代表了要操作的数据

    Uri主要包括了两部分信息:
    1. 须要操作的ContentProvider 。
    2. 对ContentProvider中的什么数据进行操作

    Uri组成部分


    • scheme:ContentProvider(内容提供者)的scheme已经由Android所规定, scheme为:content://
    • 主机名(或叫Authority):用于唯一标识这个ContentProvider,外部调用者能够依据这个标识来找到它。
    • 路径(path):能够用来表示我们要操作的数据。路径的构建应依据业务而定。
      • 要操作person表中id为10的记录,能够构建这种路径:/person/10
      • 要操作person表中id为10的记录的name字段, person/10/name
      • 要操作person表中的全部记录,能够构建这种路径:/person
      • 要操作xxx表中的记录。能够构建这种路径:/xxx
      • 当然要操作的数据不一定来自数据库。也能够是文件、xml或网络等他存储方式,例如以下:
      • 要操作xml文件里person节点下的name节点。能够构建这种路径:/person/name
    当别的应用程序要訪问此项目的时候,就须要一个訪问地址,uri就充当的这个角色,和我们訪问的url一样。例如以下:

    URL:    http://www.baidu.com/index.html 
    http://: http协议訪问站点
    www.baidu.com域名部分
     /index.html:站点资源 
    URI:     content://www.csdn.com.provider.userContentProvider/user
    content://android的ContentProvider的规定
    www.csdn.com.provider.userContentProvider:文件汇中自己配置的authorities
    user: 资源部分(数据部分)当訪问者须要訪问不同的资源时,这个部分是动态改变.这个部分能够自定义

    parse()

    假设要把一个字符串转换成Uri
    Uri uri = Uri.parse("content://cn.itcast.provider.personprovider/person")

    操作Uri

    由于Uri代表了要操作的数据,所以我们常常须要解析Uri,并从Uri中获取数据。Android系统提供了两个用于操作Uri的工具类。分别为UriMatcher 和ContentUris 。掌握它们的使用。会便于我们的开发工作。

    UriMatcher类

    • uriMatcher.addURI(authority, path, code):匹配码是调用addURI()方法传入的第三个參数
      • 參数一authority:定义的authority路径
      • 參数二path:URI路径
      • 參数三code:返回的匹配码
    • 注冊完须要匹配的Uri后,就能够使用sMatcher.match(uri)方法对输入的Uri进行匹配,假设匹配就返回匹配码。
    UriMatcher类用于匹配Uri。它的使用方法例如以下:

    把你须要匹配Uri路径所有给注冊上,例如以下:
    //常量UriMatcher.NO_MATCH表示不匹配不论什么路径的返回码
    UriMatcher  sMatcher = new UriMatcher(UriMatcher.NO_MATCH);
    //假设match()方法匹配content://cn.itcast.provider.personprovider/person路径,返回匹配码为1
    sMatcher.addURI(“cn.itcast.provider.personprovider”, “person”, 1);//加入须要匹配uri。假设匹配就会返回匹配码
    //假设match()方法匹配content://cn.itcast.provider.personprovider/person/230路径,返回匹配码为2
    sMatcher.addURI(“cn.itcast.provider.personprovider”, “person/#”, 2);//#号为通配符
    switch (sMatcher.match(Uri.parse("content://cn.itcast.provider.personprovider/person/10"))) { 
    case 1
    break;
    case 2
    break;
    default://不匹配
    break;
    }

    ContentUris类

    ContentUris类用于获取Uri路径后面的ID部分,它有两个比較有用的方法:

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

    ContentProvider中方法实现步骤

    1. 继承ContentProvider类
    2. 声明操作的标志
    3. 定义uri解析返回的匹配码
    4. 使用UriMatcher类匹配Uri
    5. 在oncreate()中实例化数据库操作对象
    6. 查询方法
      1. 匹配URI 进行推断
      2. 匹配成功进行查询
    7. 加入方法
      1. 匹配URI 进行推断
      2. 匹配成功进行加入
      3. 返回:通过ContentUris.withAppendedId加入唯一的id值
    8. 删除方法
      1. 匹配URI 进行推断
      2. 匹配成功进行删除
      3. 关闭数据库
      4. 返回:删除的行数
    9. 改动方法
      1. 匹配URI 进行推断
      2. 匹配成功进行改动
      3. 关闭数据库
      4. 返回:改动的行数
    ContentProvider中的增删改查都是依据android封装好的CURD

    ContentProvider源代码:
    package com.example.android_sqlite.provider;
    
    import com.example.android_sqlite.database.DatabaseHelper;
    
    import android.content.ContentProvider;
    import android.content.ContentUris;
    import android.content.ContentValues;
    import android.content.UriMatcher;
    import android.database.Cursor;
    import android.database.sqlite.SQLiteDatabase;
    import android.net.Uri;
    
    public class UserContentProvider extends ContentProvider {
    	// 1.操作的标志
    	private static final String AUTHORITIE = "www.csdn.com.provider.userContentProvider";
    
    	// 2.定义uri解析返回的匹配码
    	private static final int QUERY = 1;
    	private static final int INSERT = 2;
    	private static final int UPDATE = 3;
    	private static final int DELETE = 4;
    
    	private static UriMatcher uriMatcher;
    	private DatabaseHelper dh;
    
    	// 3.使用UriMatcher类匹配Uri
    	static {
    		//实例化UriMatcher对象。常量UriMatcher.NO_MATCH表示不匹配不论什么路径的返回码
    		uriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
    		// 匹配的结果码
    		uriMatcher.addURI(AUTHORITIE, "query", QUERY);
    		uriMatcher.addURI(AUTHORITIE, "insert", INSERT);
    		uriMatcher.addURI(AUTHORITIE, "update", UPDATE);
    		uriMatcher.addURI(AUTHORITIE, "delete", DELETE);
    	}
    
    	/**
    	 * 在UserContentProvider创建之后,就会被调用,当其它应用程序第一次訪问contentPrivider时。
    	 * 该ContentProvider就会被创建出来
    	 */
    	@Override
    	public boolean onCreate() {
    		dh = new DatabaseHelper(getContext());
    		return false;
    	}
    
    	/**
    	 * URL:http://www.baidu.com/index.html http://: http协议訪问站点
    	 * www.baidu.com:域名部分 /index.html:站点资源
    	 * 
    	 * URI:content://www.csdn.com.provider.userContentProvider/user
    	 * content://android的ContentProvider的规定
    	 * www.csdn.com.provider.userContentProvider:文件汇中自己配置的authorities
    	 * user:资源部分(数据部分)当訪问者须要訪问不同的资源时,这个部分是动态改变.这个部分能够自定义
    	 * 
    	 * UriMatcher:匹配uri
    	 */
    	/**
    	 * 查询方法
    	 */
    	@Override
    	public Cursor query(Uri uri, String[] projection, String selection,
    			String[] selectionArgs, String sortOrder) {
    
    		Cursor c = null;
    		// 匹配URI 进行推断
    		if (uriMatcher.match(uri) == QUERY) {
    			SQLiteDatabase db = dh.getReadableDatabase();
    			c = db.query("users", projection, selection, selectionArgs, null,
    					null, sortOrder);
    		} else {
    			System.out.println("查询操作的uri不匹配");
    		}
    		return c;
    	}
    
    	/**
    	 * 返回操作的类型 假设操作多条记录那么MINE类型vnd.android.cursor.div/开头
    	 * 假设操作的数据仅仅有一条记录那么MINE类型vnd.android.cursor.item/开头
    	 */
    	@Override
    	public String getType(Uri arg0) {
    		return null;
    
    	}
    
    	/**
    	 * 插入操作
    	 */
    	@Override
    	public Uri insert(Uri uri, ContentValues values) {
    		long rowId = 0;
    		if (uriMatcher.match(uri) == INSERT) {
    			SQLiteDatabase db = dh.getReadableDatabase();
    			rowId = db.insert("users", null, values);
    			db.close();
    		} else {
    			System.out.println("插入不匹配");
    		}
    		//通过ContentUris.withAppendedId增加唯一的id值
    		return ContentUris.withAppendedId(uri, rowId);
    	}
    
    	/**
    	 * 更新操作
    	 */
    	@Override
    	public int update(Uri uri, ContentValues values, String selection,
    			String[] selectionArgs) {
    		//更新几行
    		int count = 0;
    		if (uriMatcher.match(uri) == UPDATE) {
    			SQLiteDatabase db = dh.getWritableDatabase();
    			count = db.update("users", values, selection, selectionArgs);
    			db.close();
    		}
    		return count;
    	}
    
    	/**
    	 * 删除操作
    	 */
    	@Override
    	public int delete(Uri uri, String selection, String[] selectionArgs) {
    		//删除几行
    		int count = 0;
    		if (uriMatcher.match(uri) == DELETE) {
    			SQLiteDatabase db = dh.getWritableDatabase();
    			count = db.delete("users", selection, selectionArgs);
    			db.close();
    		}
    		return count;
    	}
    
    }
    

    AndroidManifest.xml

    <?

    xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.example.android_sqlite" android:versionCode="1" android:versionName="1.0" > <uses-sdk android:minSdkVersion="8" android:targetSdkVersion="17" /> <instrumentation android:name="android.test.InstrumentationTestRunner" android:targetPackage="com.example.android_sqlite" > </instrumentation> <application android:allowBackup="true" android:icon="@drawable/ic_launcher" android:label="@string/app_name" android:theme="@style/AppTheme" > <activity android:name="com.example.android_sqlite.MainActivitysss" android:label="@string/app_name" > <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> <uses-library android:name="android.test.runner" /> <!-- 配置ContentProvider --> <provider android:name=".provider.UserContentProvider" android:authorities="www.csdn.com.provider.userContentProvider" android:exported="true" > </provider> </application> </manifest>









  • 相关阅读:
    【iOS】7.4 定位服务->2.1.1 定位
    【iOS】7.4 定位服务->1.0 简介
    1.2.1 OC概述
    5.1 网络基础
    4.4 多线程进阶篇<下>(NSOperation)
    4.3 多线程进阶篇<中>(GCD)
    4.1/4.2 多线程进阶篇<上>(Pthread & NSThread)
    4.0 多线程基础篇
    2.1 -1.0 Xcode(发布时间、使用、快捷键、插件相关)
    一款面试复习应用源码
  • 原文地址:https://www.cnblogs.com/mengfanrong/p/5336906.html
Copyright © 2020-2023  润新知