Android数据存储之ContentProvider基本原理
2013-05-05 10:58
579 查看
对于ContentProvider,一般的使用方法是在主Activity中使用ContentResolver调用增删改查的方法去调用在ContentProvider中对应的增删改查的方法,而在ContentProvider的中通过SQLiteOpenHelper获得目标应用的可写的数据库,然后在对应的增删改查方法中对数据库进行实际操作。在此之前为了之后的操作方便先定义一个元数据接口声明各项要用到的常量,比如库表名称,URI,mime类型等
元数据代码:
然后准备好SQLiteOpenHelper
而在ContentProvider中,需要一个UriMatcher来判断传递的URI有没有id项,因为使用ContentResolver需要传入一个URI,若URI中有id项,如 content://AUTHORITY/TABLE_NAME/ID 则操作类型为vnd.android.cursor.item单项操作;否则为vnd.android.cursor.dir是多项操作
启动ContentProvider时需要初始化DatabaseOpenHelper
用插入数据举例,复写insert() 方法
而ContentResolver端通过ContentVaules键值对来传送数据
这样就完成了一次客户端向目的应用数据库插入数据的操作,但是大多数时候我们用的是系统的ContentProvider,只需操作客户端的ContentResolver,上述代码只是为了更好的理解ContentProvider的工作原理
元数据代码:
public interface DatabaseMetaData { // uri : content://com.example.mycontentprovider public static final String AUTHORITY = "com.example.contentprovideractivity.mycontentprovider"; public static final String DATABASE_NAME = "SHUAI"; public static final int VERSION = 1; public static interface MemberTableMetaData extends BaseColumns { public static final String TABLE_NAME = "member"; // 外部程序访问本表所需的URI public static final Uri CONTENT_URI = Uri.parse("content://" + AUTHORITY + "/" + TABLE_NAME); // 取得表中全部信息 public static final String CONTACT_LIST = "vnd.android.cursor.dir/vnd.mycontentprovider.member"; // 取得表中一项信息,按 id查询 public static final String CONTACT_ITEM = "vnd.android.cursor.item/vnd.mycontentprovider.member"; public static final String MEMBER_NAME = "name"; public static final String MEMBER_TELEPHONE = "telephone"; // 排序操作 public static final String SORT_ORDER = "_id DESC"; } }
然后准备好SQLiteOpenHelper
public class DatabaseOpenHelper extends SQLiteOpenHelper { public DatabaseOpenHelper(Context context) { super(context, DatabaseMetaData.DATABASE_NAME, null, DatabaseMetaData.VERSION); } @Override public void onCreate(SQLiteDatabase db) { String sql = "CREATE TABLE " + DatabaseMetaData.MemberTableMetaData.TABLE_NAME + " ( " + DatabaseMetaData.MemberTableMetaData._ID + " INTEGER PRIMARY KEY ," + DatabaseMetaData.MemberTableMetaData.MEMBER_NAME + " VARCHAR(50) NOT NULL ," + DatabaseMetaData.MemberTableMetaData.MEMBER_TELEPHONE + " VARCHAR(50) NOT NULL" + " )"; db.execSQL(sql); } @Override public void onUpgrade(SQLiteDatabase db, int oldVerson, int newVersion) { String sql = "DROP TABLE IF EXISTS " + DatabaseMetaData.MemberTableMetaData.TABLE_NAME; db.execSQL(sql); } }
而在ContentProvider中,需要一个UriMatcher来判断传递的URI有没有id项,因为使用ContentResolver需要传入一个URI,若URI中有id项,如 content://AUTHORITY/TABLE_NAME/ID 则操作类型为vnd.android.cursor.item单项操作;否则为vnd.android.cursor.dir是多项操作
public class MyContentProvider extends ContentProvider { private static UriMatcher matcher = null; private static final int GET_MEMBER_LIST = 1; private static final int GET_MEMBER_ITEM = 2; static { matcher = new UriMatcher(UriMatcher.NO_MATCH); matcher.addURI(DatabaseMetaData.AUTHORITY, DatabaseMetaData.MemberTableMetaData.TABLE_NAME, GET_MEMBER_LIST); matcher.addURI(DatabaseMetaData.AUTHORITY, DatabaseMetaData.MemberTableMetaData.TABLE_NAME + "/#", GET_MEMBER_ITEM); }
启动ContentProvider时需要初始化DatabaseOpenHelper
private DatabaseOpenHelper helper = null; @Override public boolean onCreate() { helper = new DatabaseOpenHelper(super.getContext()); return true; }
用插入数据举例,复写insert() 方法
@Override public Uri insert(Uri uri, ContentValues values) { System.out.println(" ***** = " + uri); // 获得可写数据库 SQLiteDatabase db = helper.getWritableDatabase(); long insertId = 0; switch(this.matcher.match(uri)) { case GET_MEMBER_LIST: //执行插入操作 insertId = db.insert(DatabaseMetaData.MemberTableMetaData.TABLE_NAME, DatabaseMetaData.MemberTableMetaData._ID, values); System.out.println("insert id = " + insertId); String path = uri.toString() + "/" + insertId; return Uri.parse(path); case GET_MEMBER_ITEM: return null; default: throw new UnsupportedOperationException("Not Support Operation :" + uri); } }
而ContentResolver端通过ContentVaules键值对来传送数据
private long insertTest(String name, String telephone) { // 客户端调用ContentResolver ContentResolver resolver = super.getContentResolver(); ContentValues values = new ContentValues(); values.put(DatabaseMetaData.MemberTableMetaData.MEMBER_NAME, name); values.put(DatabaseMetaData.MemberTableMetaData.MEMBER_TELEPHONE, telephone); Uri resultUri = resolver.insert(DatabaseMetaData.MemberTableMetaData.CONTENT_URI, values); System.out.println("### " + resultUri ); return ContentUris.parseId(resultUri); }
这样就完成了一次客户端向目的应用数据库插入数据的操作,但是大多数时候我们用的是系统的ContentProvider,只需操作客户端的ContentResolver,上述代码只是为了更好的理解ContentProvider的工作原理
相关文章推荐
- Android开发教程之ContentProvider数据存储
- Android之ContentProvider数据存储
- Android数据存储之ContentProvider&Preferences
- android数据存储之ContentProvider
- Android Content Provider在应用程序之间共享数据的原理分析
- (android 基础知识之数据存储) ContentResolver
- 【Android】数据存储之ContentProviders
- android contentProvider group by查询数据
- 【Android】数据存储之ContentProviders
- android 编写content_provider对外共享数据
- Android之ContentProvider跨程序共享数据入门(笔记一)
- android 编写content_provider对外共享数据
- Android之ContentProvider跨程序共享数据入门(笔记二)
- Android 存储方式之SharedPreference SQLite ContentProvider
- android ContentProvider结合SQLiteHelper实现数据的共享<一>
- Android 存储(本地存储 SD卡存储 SharedPreference SQLite ContentProvider)
- android 编写content_provider对外共享数据
- Android 存储(本地存储 SD卡存储 SharedPreference SQLite ContentProvider)
- Android进阶#(5/12)独特高效的数据存储——SQLite数据库_数据库框架ActiveAndroid的使用与基本原理
- android SQLite数据库 一次性存储多条数据