Android学习笔记ContentProvider

xiaoxiao2021-02-28  90

1.ContentProvider是个什么?

ContentProvider——内容提供者。它是一个类,这个类主要是对Android系统中进行共享的数据进行包装,并提供了一组统一的访问接口供其他程序调用。这些被共享的数据,可以使系统自己的也可以使我们个人应用程序中的数据。

2.ContentProvider有什么作用?

在Android中,数据的存储有很多种方式,最常用的就是SQLite和XML文件方式。在不同的应用程序间,其实数据是不能直接被相互访问和操作的,在这种情况下,ContentProvider很好的被用来解决了不同应用程序间数据共享的问题。 其实在Android系统中,已经为我们提供了许多ContentProvider,如:Contacts、Browser、CallLog、Settings等等。那么,Android系统中提供了这么多的ContentProvider,另外还有我们自己公开的共享数据,我们在写程序的时候,怎么才能让我们的应用程序知道去哪儿取、如何取这些数据呢?我们自然的会想到URI。

3.URI中的方法

 URI(Uniform Resource Identifier)——统一资源定位符,URI在ContentProvider中代表了要操做的数据。

    在Android系统中通常的URI格式为:content://LiB.cprovider.myprovider.Users/User/21

    在万维网访问时通常用的URI格式为:http://www.cccc.com/xx/zz

content://——schema,这个是Android中已经定义好的一个标准。 LiB.cprovider.myprovider.Users——authority(主机名),用于唯一标识这个ContentProvider,外部调用者通过这个authority来找到它。相当于www.cccc.com,代表的是我们ContentProvider所在的”域名”,这个”域名”在我们Android中一定要是唯一的,否则系统怎么能知道该找哪一个Provider呢?所以一般情况下,建议采用完整的包名加类名来标识这个ContentProvider的authority。 /User/21——路径,用来标识我们要操作的数据。/user/21表示的意思是——找到User中id为21的记录。其实这个相当于/xxx/zzz。     综上所述,content://LiB.cprovider.myprovider.Users/User/21所代表的URI的意思为:标识LiB.cprovider.myprovider中Users表中_ID为21的User项。

4.ContentProvider中公开的几个方法

public boolean onCreate():该方法在ContentProvider创建后就会被调用,Android系统运行后,ContentProvider只有在被第一次使用它时才会被创建。 public Uri insert(Uri uri, ContentValues values):外部应用程序通过这个方法向 ContentProvider添加数据。 uri——标识操作数据的URI values——需要添加数据的键值对 public int delete(Uri uri, String selection, String[] selectionArgs):外部应用程序通过这个方法从 ContentProvider中删除数据。 uri——标识操作数据的URI selection——构成筛选添加的语句,如”id=1” 或者 “id=?” selectionArgs——对应selection的两种情况可以传入null 或者 new String[]{“1”} public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs):外部应用程序通过这个方法对 ContentProvider中的数据进行更新。 values——对应需要更新的键值对,键为对应共享数据中的字段,值为对应的修改值 其余参数同delete方法 public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder):外部应用程序通过这个方法从ContentProvider中获取数据,并返回一个Cursor对象。 projection——需要从Contentprovider中选择的字段,如果为空,则返回的Cursor将包含所有的字段。 sortOrder——默认的排序规则 其余参数同delete方法     public String getType(Uri uri):该方法用于返回当前Url所代表数据的MIME类型。 如果操作的数据属于集合类型,那么MIME类型字符串应该以vnd.android.cursor.dir/开头,例如:要得到所有user记录的Uri为content:// LiB.cprovider.myprovider.Users /User,那么返回的MIME类型字符串应该为:”vnd.android.cursor.dir/user”。 如果要操作的数据属于非集合类型数据,那么MIME类型字符串应该以vnd.android.cursor.item/开头,例如:得到id为21的user记录,Uri为content:// LiB.cprovider.myprovider.Users /User/21,那么返回的MIME类型字符串为:”vnd.android.cursor.item/user”。

5.如何公开数据?

首先,继承ContentProvider并重写它的几个抽象方法 package LiB.cprovider;

import java.util.HashMap;

import LiB.cprovider.Users.User; 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.database.sqlite.SQLiteQueryBuilder; import android.net.Uri; import android.text.TextUtils;

public class myprovider extends ContentProvider {

private DBHelper dbHelper; private static final UriMatcher uriMatcher; private static final int USER = 1; private static final int USER_ID = 2; private static HashMap<String, String> maps; static { // 当没有匹配成功是时,返回NO_MATCH的值 uriMatcher = new UriMatcher(UriMatcher.NO_MATCH); // 匹配Users表中的所有User,匹配成功后返回USER整数值

// content://LiB.cprovider.myprovider.Users/User uriMatcher.addURI(Users.AUTHORITY, “User”, USER); // 匹配Users表中指定ID的User项,匹配成功后返回USER_ID整数值 // content://LiB.cprovider.myprovider.Users/User/21 uriMatcher.addURI(Users.AUTHORITY, “User/#”, USER_ID);

maps = new HashMap<String, String>(); maps.put(User._ID, User._ID); maps.put(User.NAME, User.NAME); maps.put(User.SEX, User.SEX); maps.put(User.AGE, User.AGE); } @Override public int delete(Uri uri, String selection, String[] selectionArgs) { SQLiteDatabase db = dbHelper.getWritableDatabase(); int count = 0; switch (uriMatcher.match(uri)) { case USER: count = db.delete(DBHelper.DATATABLE_NAME, selection, selectionArgs); break; case USER_ID: String noteId = uri.getPathSegments().get(1); count = db.delete(DBHelper.DATATABLE_NAME, User._ID + "=" + noteId + (!TextUtils.isEmpty(selection) ? " AND (" + selection + ')' : ""), selectionArgs); break; default: throw new IllegalArgumentException(); } this.getContext().getContentResolver().notifyChange(uri, null); return count; } @Override public String getType(Uri uri) { return null; } @Override public Uri insert(Uri uri, ContentValues values) { SQLiteDatabase db = dbHelper.getWritableDatabase(); // User.NAME不能为空 long _id = db.insert(DBHelper.DATATABLE_NAME, User.NAME, values); if (_id > 0) { Uri uri1 = ContentUris.withAppendedId(User.CONTENT_URI, _id); this.getContext().getContentResolver().notifyChange(uri1, null); return uri1; } return null; } @Override public boolean onCreate() { dbHelper = new DBHelper(this.getContext()); return true; } @Override public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) { SQLiteQueryBuilder sqb = new SQLiteQueryBuilder(); switch (uriMatcher.match(uri)) { case USER: sqb.setTables(DBHelper.DATATABLE_NAME); sqb.setProjectionMap(maps); break; case USER_ID: sqb.setTables(DBHelper.DATATABLE_NAME); sqb.setProjectionMap(maps); sqb.appendWhere(User._ID + "=" + uri.getPathSegments().get(1)); break; default: throw new IllegalArgumentException(); } SQLiteDatabase db = dbHelper.getReadableDatabase(); Cursor cursor = sqb.query(db, projection, selection, selectionArgs, null, null, null); cursor.setNotificationUri(getContext().getContentResolver(), uri); return cursor; } @Override public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) { SQLiteDatabase db = dbHelper.getWritableDatabase(); int count; switch (uriMatcher.match(uri)) { case USER: count = db.update(DBHelper.DATATABLE_NAME, values, selection, selectionArgs); break; case USER_ID: String noteId = uri.getPathSegments().get(1); count = db.update(DBHelper.DATATABLE_NAME, values, User._ID + "=" + noteId + (!TextUtils.isEmpty(selection) ? " AND (" + selection+ ')' : ""), selectionArgs); break; default: throw new IllegalArgumentException(); } getContext().getContentResolver().notifyChange(uri, null); return count; }

}

6.怎么操作我自己的数据呢?

为了方便我们操作ContentProvider,Android系统为我们提供了ContentResolver类。我们可以使用getContentResolver()方法返回一个ContentResolver对象,并使用它与ContentProvider对应的方法来进行操作。

总结 

其实在Android中,系统已经为我们提供了许多的ContentProvider了,我们通常情况下是不需要去自定义ContentProvider的。但是,为了更好的理解ContentProvider,自己来实现一个ContentProvider是非常必要的。

作者:唐如璇:原文地址

转载请注明原文地址: https://www.6miu.com/read-21477.html

最新回复(0)