数据存贮
来源:互联网 发布:淘宝香港it代购真假 编辑:程序博客网 时间:2024/06/10 02:51
转载来源:http://blog.csdn.net/geekerparadise/article/details/7787729
接触Android有一段时间了,每一个知识点都有涉及,现在觉得重新把知识点理一遍很重要,那么就凭感觉、凭喜好无知识点先后顺序来理清一遍。这篇文章主要叙述了如何来自定义自己的ContentProvider组件,其中涉及到的一些比较重要的知识点也顺带详细分解一下,那么现在就开始吧。
一、SQLiteOpenHelper简介:
SQLiteOpenHelper是Android给我们提供的一个工具,用来和数据库交互的。我们通常使用的方法是自定义一个类来继承于SQLiteOpenHelper,通过它可以得到一个SQLiteDatabase的实例,通过使用此对象的一些方法来与数据库交互。
例如:
execSQL(Stringsql).传入一个字符串形式的sql语句来执行等。
insert(String table, String nullColumnHack, ContentValues values)。插入操作,table是表名,values是ContentValues类型用来携带数据的,第二个参数是为了防止values为空时后台创建SQL语句出错。具体的其他方法参考API文档,此处就不做解释。
二、ContentProvider简介:
假如你的应用程序想把一些数据提供给其他的应用程序来使用,那么此时就会用到ContentProvider,有了它你的应用程序就可以在进程间共享数据。使用的时候需要创建一个类来继承ContentProvider,实现里面的方法,这就相当于此应用给其他应用程序提供访问数据的接口。说直观点,Contentprovider就相当于一个中介人,它介于第一个应用程序的数据层和另一应用程序之间。使用了Contentprovider最重要的作用是统一了共享数据时访问数据的方式。
三、ContentResolver简介:
当外部应用程序想对ContentProvider中数据进行操作时可以使用ContentResolver来完成,要获取它的对象可以使用Activity中的getContentResolver方法来完成。
四、Uri简介:
介绍之前默认为大家都了解URL,那么URL就相当于Uri的一个子集。Uri由三部分组成:scheme、authority、path。下面举一个例子来具体介绍。
Uri: content://com.jm.provider.myprovider/peoples
1 scheme部分:以content://开头,是Android系统定义的,不可更改。
2 authority部分:推荐以域名+provider+类名组成,也可自己定义。
3 path部分:用来表示我们要操作的数据。具体说明如下:
要操作peoples中所有数据可以构建 /peoples
要操作peoples中_id为1的数据可以构建/peoples/1
Uri有两个比较常用方法
1 parse(String uriString)它的作用是将字符型数据转换成Uri类型数据。
2 withAppendedPath(Uri baseUri,String pathSegment)它的作用是将baseUri后面加上pathSegment组成新的Uri。
五、UriMatcher简介:
作用是在ContentProvider中把需要匹配的Uri全部注册上。
UriMatcher.NO_MATCHER表示不匹配任何路径,返回码为-1.
UriMatcher有两个常用方法。
1 match(Uri uri)获取路径的返回码。
2 addURI(String authority, Stringpath, int code)是用来注册需要匹配的路径。具体实例参看下文。
API中推荐把它放在静态块中完成,例如:
- private static final UriMatcher mather = new UriMatcher(UriMatcher.NO_MATCH);
- static {
- mather.addURI(CONTENT_URI.getAuthority(), "peoples", PEOPLE);
- mather.addURI(CONTENT_URI.getAuthority(), "peoples/#", PEOPLE_ID);
- }
private static final UriMatcher mather = new UriMatcher(UriMatcher.NO_MATCH);static {mather.addURI(CONTENT_URI.getAuthority(), "peoples", PEOPLE);mather.addURI(CONTENT_URI.getAuthority(), "peoples/#", PEOPLE_ID);}
其中要解释的一点是#代表通配符,表示所有数字(will match any number)。*代表所有字符(will match any text)。
六、ContentUris简介:
ContentUris是用来获取uri后面id部分,它有两个比较实用的方法:
1 parseId(Uri contentUri)用来获得contentUri中id部分
2 withAppendedId(Uri contentUri,long id)用来给contentUri添加id组成新的Uri,功能和Uri的withAppendedPath(Uri baseUri,String pathSegment)方法类似。
七、ContentProvider中getType方法中MIME类型讲解:
vnd.android.cursor.dir代表值的集合
vnd.android.cursor.item代表一项值
最好不要默认返回null
结构分析,例如:"vnd.android.cursor.dir/peoplelist" 斜杠前部分可把它比作变量的类型是不能随便定义的,后部分相当于变量名,可自己定义。
当调用增删改查方法时系统会通过getType()进行验证,如果有值并且是系统可识别的类型,那么处理起来比较快。
八、代码示例:
1、继承SQLiteOpenHelper
- package com.jm.my.provider;
- import android.content.ContentValues;
- import android.content.Context;
- import android.database.sqlite.SQLiteDatabase;
- import android.database.sqlite.SQLiteOpenHelper;
- /**
- * 继承于SQLiteOpenHelper,用于和数据库交互
- * @author jinmeng
- * @date 2012-7-25
- * @version 1.0
- */
- public class MyHelper extends SQLiteOpenHelper {
- //数据库名字,可在文件目录下找到
- private static final String DATABASE_NAME = "mydb";
- //数据库版本号
- private static final int MYDATABASE_VERSION = 1;
- //数据库表名
- public static final String TABLE_NAME = "peoples";
- //数据库的一些基本字段
- public static final String COL_NAME = "name";
- public static final String COL_AGE = "age";
- public static final String COL_BIRTHDAY = "birthday";
- //创建数据库时的SQL语句
- public static final String CREATEDATABASE = "CREATE TABLE " + TABLE_NAME
- + " (_id INTEGER PRIMARY KEYAUTOINCREMENT, " + COL_NAME
- + " TEXT, " + COL_AGE + " INTEGER, " + COL_BIRTHDAY + " DATE);";
- public MyHelper(Context context) {
- super(context, DATABASE_NAME, null, MYDATABASE_VERSION);
- }
- /**
- * 当数据库被创建的时候执行SQL语句
- */
- @Override
- public void onCreate(SQLiteDatabase db) {
- db.execSQL(CREATEDATABASE);
- ContentValues cv = new ContentValues();
- cv.put(COL_NAME, "jinmeng");
- cv.put(COL_AGE, 22);
- String str = new String("1990-03-09");
- cv.put(COL_BIRTHDAY, str);
- db.insert(TABLE_NAME, null, cv);
- }
- /**
- * 当数据库版本号更新的时候回调此方法。
- */
- @Override
- public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
- db.execSQL("DROP TABLE IF EXIST" + TABLE_NAME);
- onCreate(db);
- }
- }
package com.jm.my.provider; import android.content.ContentValues;import android.content.Context;import android.database.sqlite.SQLiteDatabase;import android.database.sqlite.SQLiteOpenHelper; /** * 继承于SQLiteOpenHelper,用于和数据库交互 * @author jinmeng * @date 2012-7-25 * @version 1.0 */public class MyHelper extends SQLiteOpenHelper { //数据库名字,可在文件目录下找到 private static final String DATABASE_NAME = "mydb"; //数据库版本号 private static final int MYDATABASE_VERSION = 1; //数据库表名 public static final String TABLE_NAME = "peoples"; //数据库的一些基本字段 public static final String COL_NAME = "name"; public static final String COL_AGE = "age"; public static final String COL_BIRTHDAY = "birthday"; //创建数据库时的SQL语句 public static final String CREATEDATABASE = "CREATE TABLE " + TABLE_NAME + " (_id INTEGER PRIMARY KEYAUTOINCREMENT, " + COL_NAME + " TEXT, " + COL_AGE + " INTEGER, " + COL_BIRTHDAY + " DATE);"; public MyHelper(Context context) { super(context, DATABASE_NAME, null, MYDATABASE_VERSION); } /** * 当数据库被创建的时候执行SQL语句 */ @Override public void onCreate(SQLiteDatabase db) { db.execSQL(CREATEDATABASE); ContentValues cv = new ContentValues(); cv.put(COL_NAME, "jinmeng"); cv.put(COL_AGE, 22); String str = new String("1990-03-09"); cv.put(COL_BIRTHDAY, str); db.insert(TABLE_NAME, null, cv); } /** * 当数据库版本号更新的时候回调此方法。 */ @Override public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { db.execSQL("DROP TABLE IF EXIST" + TABLE_NAME); onCreate(db); }}
2、为示例添加ContentProvider类:
- package com.jm.my.provider;
- 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;
- /**
- * 继承于ContentProvider,提供外接访问接口
- *
- * @author jinmeng
- * @date 2012-7-25
- * @version 1.0
- */
- public class MyProvider extends ContentProvider {
- // 和Authority相关
- public static final Uri CONTENT_URI = Uri
- .parse("content://com.jm.provider.myprovider/peoples");
- // 数据库表名
- private static final String TABLE_NAME = "peoples";
- // 注册和解析路径时的返回码
- private static final int PEOPLE = 1;
- private static final int PEOPLE_ID = 2;
- // 注册需要的路径
- private static final UriMatcher mather = new UriMatcher(UriMatcher.NO_MATCH);
- static {
- mather.addURI(CONTENT_URI.getAuthority(), "peoples", PEOPLE);
- mather.addURI(CONTENT_URI.getAuthority(), "peoples/#", PEOPLE_ID);
- }
- private MyHelper helper;
- /**
- * 基本表结构
- *
- * @author jinmeng
- *
- */
- public static final class Mydata {
- public static final String COL_ID = "_id";
- public static final String COL_NAME = "name";
- public static final String COL_AGE = "age";
- public static final String COL_BIRTHDAY = "birthday";
- }
- @Override
- public boolean onCreate() {
- this.helper = new MyHelper(this.getContext());
- if (helper != null) {
- return true;
- } else {
- return false;
- }
- }
- /**
- * 启动时涉及到的MIME类型值: vnd.android.cursor.dir代表值的集合 vnd.android.cursor.item代表一项值
- * 最好不要默认返回空
- */
- @Override
- public String getType(Uri uri) {
- switch (mather.match(uri)) {
- case PEOPLE:
- return "vnd.android.cursor.dir/peoplelist";
- case PEOPLE_ID:
- return "vnd.android.cursor.item/peopleitem";
- default:
- throw new IllegalArgumentException("uri Illegal" + uri);
- }
- }
- /**
- * 具体的查询方法
- */
- @Override
- public Cursor query(Uri uri, String[] projection, String selection,
- String[] selectionArgs, String sortOrder) {
- SQLiteDatabase db = helper.getWritableDatabase();
- switch (mather.match(uri)) {
- case PEOPLE:
- return db.query(TABLE_NAME, projection, selection, selectionArgs,
- null, null, sortOrder);
- case PEOPLE_ID:
- long id = ContentUris.parseId(uri);
- String where = "_id=" + id;
- if ((selection != null) && (!"".equals(selection))) {
- where = where + " and " + selection;
- }
- return db.query(TABLE_NAME, projection, where, selectionArgs, null,
- null, sortOrder);
- default:
- throw new IllegalArgumentException("uri Illegal" + uri);
- }
- }
- /**
- * 具体的插入方法
- */
- @Override
- public Uri insert(Uri uri, ContentValues values) {
- SQLiteDatabase db = helper.getWritableDatabase();
- long id;
- switch (mather.match(uri)) {
- case PEOPLE:
- id = db.insert(TABLE_NAME, "_id", values);
- return ContentUris.withAppendedId(uri, id);
- case PEOPLE_ID:
- id = db.insert(TABLE_NAME, "_id", values);
- String uriPath = uri.toString();
- String path = uriPath.substring(0, uriPath.lastIndexOf("/")) + id;
- return Uri.parse(path);
- default:
- throw new IllegalArgumentException("uri Illegal" + uri);
- }
- }
- /**
- * 具体的删除方法
- */
- @Override
- public int delete(Uri uri, String selection, String[] selectionArgs) {
- SQLiteDatabase db = helper.getWritableDatabase();
- switch (mather.match(uri)) {
- case PEOPLE:
- return db.delete(TABLE_NAME, selection, selectionArgs);
- case PEOPLE_ID:
- long id = ContentUris.parseId(uri);
- String where = "_id=" + id;
- if ((selection != null) && (!"".equals(selection))) {
- where = where + " and " + selection;
- }
- return db.delete(TABLE_NAME, where, selectionArgs);
- default:
- throw new IllegalArgumentException("uri Illegal" + uri);
- }
- }
- /**
- * 具体的更新方法
- */
- @Override
- public int update(Uri uri, ContentValues values, String selection,
- String[] selectionArgs) {
- SQLiteDatabase db = helper.getWritableDatabase();
- switch (mather.match(uri)) {
- case PEOPLE:
- return db.update(TABLE_NAME, values, selection, selectionArgs);
- case PEOPLE_ID:
- long id = ContentUris.parseId(uri);
- String where = "_id=" + id;
- if ((selection != null) && (!"".equals(selection))) {
- where = where + " and " + selection;
- }
- return db.update(TABLE_NAME, values, where, selectionArgs);
- default:
- throw new IllegalArgumentException("uri Illegal" + uri);
- }
- }
- }
package com.jm.my.provider;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;/** * 继承于ContentProvider,提供外接访问接口 * * @author jinmeng * @date 2012-7-25 * @version 1.0 */public class MyProvider extends ContentProvider {// 和Authority相关public static final Uri CONTENT_URI = Uri.parse("content://com.jm.provider.myprovider/peoples");// 数据库表名private static final String TABLE_NAME = "peoples";// 注册和解析路径时的返回码private static final int PEOPLE = 1;private static final int PEOPLE_ID = 2;// 注册需要的路径private static final UriMatcher mather = new UriMatcher(UriMatcher.NO_MATCH);static {mather.addURI(CONTENT_URI.getAuthority(), "peoples", PEOPLE);mather.addURI(CONTENT_URI.getAuthority(), "peoples/#", PEOPLE_ID);}private MyHelper helper;/** * 基本表结构 * * @author jinmeng * */public static final class Mydata {public static final String COL_ID = "_id";public static final String COL_NAME = "name";public static final String COL_AGE = "age";public static final String COL_BIRTHDAY = "birthday";}@Overridepublic boolean onCreate() {this.helper = new MyHelper(this.getContext());if (helper != null) {return true;} else {return false;}}/** * 启动时涉及到的MIME类型值: vnd.android.cursor.dir代表值的集合 vnd.android.cursor.item代表一项值 * 最好不要默认返回空 */@Overridepublic String getType(Uri uri) {switch (mather.match(uri)) {case PEOPLE:return "vnd.android.cursor.dir/peoplelist";case PEOPLE_ID:return "vnd.android.cursor.item/peopleitem";default:throw new IllegalArgumentException("uri Illegal" + uri);}}/** * 具体的查询方法 */@Overridepublic Cursor query(Uri uri, String[] projection, String selection,String[] selectionArgs, String sortOrder) {SQLiteDatabase db = helper.getWritableDatabase();switch (mather.match(uri)) {case PEOPLE:return db.query(TABLE_NAME, projection, selection, selectionArgs,null, null, sortOrder);case PEOPLE_ID:long id = ContentUris.parseId(uri);String where = "_id=" + id;if ((selection != null) && (!"".equals(selection))) {where = where + " and " + selection;}return db.query(TABLE_NAME, projection, where, selectionArgs, null,null, sortOrder);default:throw new IllegalArgumentException("uri Illegal" + uri);}}/** * 具体的插入方法 */@Overridepublic Uri insert(Uri uri, ContentValues values) {SQLiteDatabase db = helper.getWritableDatabase();long id;switch (mather.match(uri)) {case PEOPLE:id = db.insert(TABLE_NAME, "_id", values);return ContentUris.withAppendedId(uri, id);case PEOPLE_ID:id = db.insert(TABLE_NAME, "_id", values);String uriPath = uri.toString();String path = uriPath.substring(0, uriPath.lastIndexOf("/")) + id;return Uri.parse(path);default:throw new IllegalArgumentException("uri Illegal" + uri);}}/** * 具体的删除方法 */@Overridepublic int delete(Uri uri, String selection, String[] selectionArgs) {SQLiteDatabase db = helper.getWritableDatabase();switch (mather.match(uri)) {case PEOPLE:return db.delete(TABLE_NAME, selection, selectionArgs);case PEOPLE_ID:long id = ContentUris.parseId(uri);String where = "_id=" + id;if ((selection != null) && (!"".equals(selection))) {where = where + " and " + selection;}return db.delete(TABLE_NAME, where, selectionArgs);default:throw new IllegalArgumentException("uri Illegal" + uri);}}/** * 具体的更新方法 */@Overridepublic int update(Uri uri, ContentValues values, String selection,String[] selectionArgs) {SQLiteDatabase db = helper.getWritableDatabase();switch (mather.match(uri)) {case PEOPLE:return db.update(TABLE_NAME, values, selection, selectionArgs);case PEOPLE_ID:long id = ContentUris.parseId(uri);String where = "_id=" + id;if ((selection != null) && (!"".equals(selection))) {where = where + " and " + selection;}return db.update(TABLE_NAME, values, where, selectionArgs);default:throw new IllegalArgumentException("uri Illegal" + uri);}}}
3、添加contentProvider配置:
此处定义的
- android:authorities
android:authorities和代码中CONTENT_URI保持一致
- <providerandroid:name=".MyProvider"
- android:authorities="com.jm.provider.myprovider"/>
<providerandroid:name=".MyProvider"android:authorities="com.jm.provider.myprovider"/>
4、测试ContentProvider的示例程序:
ContentProvider是给其他应用程序提供数据的接口,那么测试工程新建,以下只给出insert的测试。
- package com.jm.test;
- import android.app.Activity;
- import android.content.ContentResolver;
- import android.database.Cursor;
- import android.net.Uri;
- import android.os.Bundle;
- import android.util.Log;
- /**
- * 用来测试ContentProvider
- * @author jinmeng
- * @date 2012-7-25
- * @version 1.0
- */
- public class MainActivity extends Activity {
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- //获取ContentResolver实例
- ContentResolver contentResolver = MainActivity.this
- .getContentResolver();
- //访问数据的Uri地址
- Uri uri = Uri.parse("content://com.jm.provider.myprovider/peoples");
- //通过ContentResolver来获取Cursor
- Cursor cursor = contentResolver.query(uri, new String[] { "_id",
- "name", "age" }, null, null, "_id desc");
- //遍例输出结果
- while (cursor.moveToNext()) {
- Log.i("jm",
- "_id=" + cursor.getInt(0) + ",name=" + cursor.getString(1)
- + ",age=" + cursor.getString(2));
- }
- }
- }
- 数据存贮
- android数据存贮
- 用XML做为数据存贮格式
- 用XML做为数据存贮格式
- java 存贮二进制数据到sqlserver数据库
- SharedPreferences轻量级数据存贮,键值对形式
- android 本地数据存贮之sharedpreference
- android本地数据存贮之sqlite
- GreenDao网路网络数据获取存贮本地
- Hive语言手册之四:压缩数据存贮与应用
- JAVA基础2(数据的存贮形式)
- 存贮byte[]
- 临时存贮
- 存贮信息量
- 存贮beatbox
- 存贮过程
- 使用Phonegap(Cordova)插件将数据存贮到Native设备的Sqlite数据库中
- 存贮过程实践
- java访问权限控制符
- Silverlight WCF RIA服务(十五)数据 5
- 转 -- 最值得公司经理学习的创业七大原则
- 关于JVM INSTR iadd(混淆后的反编译)
- Silverlight WCF RIA服务(十六)表示模型
- 数据存贮
- struts2.x学习一(搭建一个简单的Struts2应用)
- android自动化测试辅助工具Weinre
- 一个轻量级的jQuery拖拽排序插件 - HTML5 Sortable
- Boost的转换函数polymorphic_cast和polymorphic_downcast
- Silverlight WCF RIA服务(十七)数据 7
- 关于JVM INSTR swap赋值
- Connect the Cities&&http://acm.hdu.edu.cn/showproblem.php?pid=3371
- Android Launcher抽屉类SlidingDrawer的使用