Android数据持久化之ContentProvider机制详解

本文实例讲述了Android数据持久化之ContentProvider机制。分享给大家供大家参考,具体如下:

一般而言,android操作系统的应用程序所建立的数据只允许自己使用,应用程序彼此间无法借助公用存储器来共享数据,android系统提供了一个机制,即内容提供器(ContentProvider),来公开自己私有的数据到数据内容器,通过该机制,可以供其他应用程序来读取自己内部的数据,当然也可以访问其他应用程序的数据。通常,内容提供器背后都有SQLite数据库的支持,用以存储内容提供内部数据。

实现ContentProvider与实现SQLite的区别:

应用程序实现SQLite时,由应用程序直接与数据库进行对接,所以要在应用程序中实现SQLite的接口:db.onCreate()、db.insert()、db.update()、db.delete()、db.query()和db.close();

实现内容提供器时,在应用程序与数据库之间要实现一个ContentProvider程序,这个ContentProvider程序会直接与数据库进行对接,此时应用程序需要实现和ContentProvider程序接口的方法。

下面该说说如何建立内容提供器了:

首先,实现内容提供器接口:

实现该接口的5个重要方法;

其次,定义数据Uri:

提供器应用程序需要定义一个“基底”Uri,以供其他应用程序访问这一内容提供器,这一个Uri必须是唯一的,且必须是以“content://”开头,content:   表示内容提供器程序所控制数据的位置;在AndroidManifest.xml配置文件中添加如下代码以进行声明:

<!-- 设置类名和授权 multiprocess属性是数据的同步性(同一时间可能有多个程序访问该内容提供器)--> <provider android:name="ContentProviderClass" android:multiprocess="true" android:authorities="com.example.data_contentprovider.ContentProviderClass" > </provider>

在应用程序中添加如下代码:

//acquire the Uri of ContentProvider getIntent().setData(Uri.parse("content://com.example.data_contentprovider.ContentProviderClass")); Uri uri = getIntent().getData();

定义一个Uri所在的位置,并设置一个变量来找到内容提供器程序的接口;

如下是一个完整的代码,功能是实现内容提供器的建立以及通过该内容提供器程序来添加和检索数据:

实现内容提供器接口的代码:

package com.example.data_contentprovider; import com.example.data_contentprovider.DB.DBHelper; import android.net.Uri; import android.content.ContentProvider; import android.content.ContentValues; import android.database.Cursor; import android.database.sqlite.SQLiteDatabase; import android.database.sqlite.SQLiteQueryBuilder; public class ContentProviderClass extends ContentProvider { DBHelper dataBaseHelper; // 定义DataBaseHelper类变量dataBaseHelper // 实现ContentProvider的onCreate方法 @Override public boolean onCreate() { // TODO Auto-generated method stub dataBaseHelper = new DBHelper(getContext()); return true; } @Override public Uri insert(Uri uri, ContentValues values) { // TODO Auto-generated method stub SQLiteDatabase db = dataBaseHelper.getWritableDatabase(); db.insert("test", null, values); return null; } @Override public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) { // TODO Auto-generated method stub SQLiteDatabase db = dataBaseHelper.getReadableDatabase(); SQLiteQueryBuilder queryBuilder = new SQLiteQueryBuilder(); queryBuilder.setTables("test"); Cursor cursor = queryBuilder.query(db, projection, selection, selectionArgs, null, null, null); return cursor; } @Override public int delete(Uri uri, String selection, String[] selectionArgs) { // TODO Auto-generated method stub return 0; } @Override public String getType(Uri uri) { // TODO Auto-generated method stub return null; } @Override public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) { // TODO Auto-generated method stub return 0; } }

配置AndroidManifest.xml文件:

<!-- 设置类名和授权 multiprocess属性是数据的同步性(同一时间可能有多个程序访问该内容提供器)--> <provider android:name="ContentProviderClass" android:multiprocess="true" android:authorities="com.example.data_contentprovider.ContentProviderClass" > </provider>

建立一个SQLite数据库系统来存储和管理数据,同时利用SQLiteOpenHilper类协助建立数据库和SQLiteDatabase类来管理数据库:

package com.example.data_contentprovider.DB; import android.content.Context; import android.database.sqlite.SQLiteDatabase; import android.database.sqlite.SQLiteOpenHelper; import android.provider.BaseColumns; public class DBHelper extends SQLiteOpenHelper { // 建立test.db数据库 public DBHelper(Context context) { super(context, "test.db", null, 1); } // 建立test表 @Override public void onCreate(SQLiteDatabase db) { db.execSQL("create table test (" + BaseColumns._ID + "integer primary key," + "name text," + "description text" + ");"); } // 更新新版本 @Override public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { db.execSQL("DROP TABLE IF EXISTS test"); onCreate(db); } }

下面就是provider的应用程序了:

package com.example.data_contentprovider; import java.util.ArrayList; import java.util.HashMap; import java.util.Map; import android.app.Activity; import android.content.ContentValues; import android.database.Cursor; import android.net.Uri; import android.os.Bundle; import android.widget.ListView; import android.widget.SimpleAdapter; public class ContentProviderActivity extends Activity { String [] from = {"column00","column01","column02"}; @SuppressWarnings("deprecation") @Override protected void onCreate(Bundle savedInstanceState) { // TODO Auto-generated method stub super.onCreate(savedInstanceState); //acquire the Uri of ContentProvider getIntent().setData(Uri.parse("content://com.example.data_contentprovider.ContentProviderClass")); Uri uri = getIntent().getData(); //create some data to test ContentValues values = new ContentValues(); values.put("name", "marry"); values.put("description", "123456"); getContentResolver().insert(uri, values); //获取ContentResolver对象(在应用程序B中,通过ContentResolver获取程序A的ContentProvider中的数据。) values.put("name", "hello"); values.put("description", "654321"); getContentResolver().insert(uri, values); //search db all colum,cursor point to first colum of result Cursor cursor = managedQuery(uri, null, null, null, null); cursor.moveToFirst(); //set ArrayList,view more field table ArrayList<Map<String,Object>> data = new ArrayList<Map<String,Object>>(); Map<String, Object> item; //from db read data and save to ArrayList data container for (int i = 0; i < cursor.getCount(); i++) { item = new HashMap<String, Object>(); item.put("column00", cursor.getString(0)); item.put("column01", cursor.getString(1)); item.put("column02", cursor.getString(2)); data.add(item); cursor.moveToNext(); } cursor.close(); //ArrayList container data save to listView ListView listView = new ListView(this); SimpleAdapter adapter = new SimpleAdapter(this, data, R.layout.activity_content_provider, from, new int[]{R.id.text1,R.id.text2,R.id.text3}); listView.setAdapter(adapter); setContentView(listView); } }

provider应用程序就可以通过该内容提供器检索数据库并向其添加数据了。

ContentProvider中重要的几个类:

UriMatcher:

要了解UriMatcher,首先需要了解android中的Uri表示方法,众所周知,Uri为通用资源标识符,它代表的是要操作的数据,Android中的每一种资源(比如文本,图像,视频等)都可以用Uri来表示。Android中的Uri由以下三部分组成:”content://”(即authory),数据的路径,资源标识ID(可选),其中如果存在ID,则表示某一个具体的资源,如果不存在ID,则表示路径下的整体。因此addUri()函数的3个参数也是对应上面的那3个。UriMatcher的匹配过程分为3步:初始化UriMatcher;注册需要用的Uri;与已经注册的Uri进行匹配。

ContentResolver :

当使用ContentProvider在不同的应用程序中共享数据时,其数据的暴露方式是采取类似数据库中表的方法。而ContentResolver 是恰好是采用类似数据库的方法来从ContentProvider中存取数据的,它是通过Uri来查询ContentProvider中提供的数据,查询时,还需知道目的数据库的名称,数据段的数据类型,或者说资源的ID。

SQLiteQueryBuilder:

是一个用来生产SQL查询语句的辅助类,可以方便的去访问SQLiteDatabase. 在构造SQL查询语句时,它同样也需要指定表名,指定列名,指定where条件等。

更多关于Android相关内容感兴趣的读者可查看本站专题:《Android资源操作技巧汇总》、《Android编程开发之SD卡操作方法汇总》、《Android文件操作技巧汇总》、《Android数据库操作技巧总结》、《Android编程之activity操作技巧总结》、《Android开发入门与进阶教程》、《Android视图View技巧总结》及《Android控件用法总结》

希望本文所述对大家Android程序设计有所帮助。

时间: 2024-09-21 23:43:47

Android数据持久化之ContentProvider机制详解的相关文章

Android数据持久化之Preferences机制详解

本文实例讲述了Android数据持久化之Preferences机制.分享给大家供大家参考,具体如下: 在Android中,实现数据持久化有五种方式:Preferences,文件File,I/O操作.SQLite数据库,ContentProvider组件. 下面逐个做一简单的介绍: 一.Preferences的介绍: Preferences是一种轻量级的数据存储机制,他将一些简单的数据类型的数据,包括boolean类型,int类型,float类型,long类型以及String类型的数据,以键值对的

Android数据持久化之File机制分析

本文实例讲述了Android数据持久化之File机制.分享给大家供大家参考,具体如下: 在使用Java SE平台开发C/S结构的软件中,File 的IO输入输出流的使用率是非常高的,通过使用IO输入输出流可以对存储介质上的文件进行读写操作,下面的代码就是实现一个在Android平台上使用File对象操作文件的功能: package com.example.data_file; import java.io.File; import java.io.FileInputStream; import

Android开发之触摸事件处理机制详解

android触碰消息传递机制 用户的每次触碰(onClick,onLongClick,onScroll,etc.)都是由一个ACTION_DOWN+n个ACTION_MOVE+1个ACTION_UP组成的,用户触碰必先有个ACTION_DOWN响应,用户触碰结束必然会有个ACTION_UP.(当然如果在途中被拦截,就可能不会有了!)那么View是如何分发消息和拦截消息呢? 1.View及其子类都会有的两个方法: public boolean dispatchTouchEvent(MotionE

iOS数据持久化-SQLite数据库使用详解

使用SQLite数据库 创建数据库 创建数据库过程需要3个步骤: 1.使用sqlite3_open函数打开数据库: 2.使用sqlite3_exec函数执行Create Table语句,创建数据库表: 3.使用sqlite3_close函数释放资源. 这个过程中使用了3个SQLite3函数,它们都是纯C语言函数,通过Objective-C去调用C函数当然不是什么问题,但是也要注意Objective-C数据类型与C数据类型兼容性问题. 下面我们使用SQLite技术实现备忘录案例,与属性列表文件实现

Android数据持久化之读写SD卡中内容的方法详解

本文实例讲述了Android数据持久化之读写SD卡中内容的方法.分享给大家供大家参考,具体如下: 前面文章里讲的那三个方法:openFileOutput .openFileInput 虽然都能通过流对象OutputStream和InputStream可以处理任意文件中的数据,但与 SharedPreferences 一样,只能在手机内存的指定目录下建立文件,因此,在实际的开发使用中有很大的局限性,那么在这一节中,我们来看一个比较高级的方法来实现数据的持久化--读写SD卡上的内容. --读取ass

Android数据持久化之I/O操作详解

本文实例讲述了Android数据持久化之I/O操作.分享给大家供大家参考,具体如下: 前面文章里我们简单的介绍了File的操作,这一节来说说使用android平台自带对象实现文件的基本操作 主要的两个类:openFileOutput(写)和openFileInput(读) 向文件中写如数据代码如下: //向文件写入内容 try { OutputStream os = openFileOutput("file-io.txt", Context.MODE_PRIVATE); String

ActiveMQ消息传送机制以及ACK机制详解 AcitveMQ是作为一种消息存储和分发组件,涉及到client与broker端数据交互的方方面面,它不仅要担保消息的存储安全性,还要提供额外的

ActiveMQ消息传送机制以及ACK机制详解     AcitveMQ是作为一种消息存储和分发组件,涉及到client与broker端数据交互的方方面面,它不仅要担保消息的存储安全性,还要提供额外的手段来确保消息的分发是可靠的.   一. ActiveMQ消息传送机制     Producer客户端使用来发送消息的, Consumer客户端用来消费消息:它们的协同中心就是ActiveMQ broker,broker也是让producer和consumer调用过程解耦的工具,最终实现了异步RPC

Android事件的分发机制详解_Android

在分析Android事件分发机制前,明确android的两大基础控件类型:View和ViewGroup.View即普通的控件,没有子布局的,如Button.TextView. ViewGroup继承自View,表示可以有子控件,如Linearlayout.Listview这些.今天我们先来了解View的事件分发机制. 先看下代码,非常简单,只有一个Button,分别给它注册了OnClick和OnTouch的点击事件. btn.setOnClickListener(new View.OnClick

数据-java中android中onTouchEvent方法的问题详解,谢谢解答!

问题描述 java中android中onTouchEvent方法的问题详解,谢谢解答! public boolean onTouchEvent(MotionEvent event) { //调用warp方法根据触摸屏事件的座标点来扭曲verts数组 warp(event.getX(), event.getY()); return true; } //MotionEvent event这两个哪个是数据类型,哪个是数值 //event.getX(), event.getY() 返回的是什么值是什么数