戏说江湖静如水,游荡江湖才有情。我就是江湖中的一个戏子。
俗话说,入行先入门。作为一名android学习者,四大组件是android中的核心组件,岂有不学之理。然而,本人才疏学浅,叙述略有不当之处,敬请谅解。
ContentProvider为存储和提供数据提供统一的接口,可以在不同的应用程序间共享数据。
ContentProvider
1.在AndroidMainfest.xml中声明
<provider
android:authorities="com.android.test.TestContentProvider"
android:name=".TestContentProvider"/>
authorities是ContentProvider的唯一表示,,让系统可以方便的找到对应的ContentProvider以便进行操作。
这样我们的自定义的ContentProvider就声明好了,现在来实现。
2.继承并实现ContentProvider的方法
public class TestContentProvider extends ContentProvider {
@Override
public boolean onCreate() {
return false;
}
@Nullable
@Override
public Cursor query(@NonNull Uri uri, @Nullable String[] strings, @Nullable String s, @Nullable String[] strings1, @Nullable String s1) {
return null;
}
@Nullable
@Override
public String getType(@NonNull Uri uri) {
return null;
}
@Nullable
@Override
public Uri insert(@NonNull Uri uri, @Nullable ContentValues contentValues) {
return null;
}
@Override
public int delete(@NonNull Uri uri, @Nullable String s, @Nullable String[] strings) {
return 0;
}
@Override
public int update(@NonNull Uri uri, @Nullable ContentValues contentValues, @Nullable String s, @Nullable String[] strings) {
return 0;
}
}
SqliteOpenHelper
我们可以看到,继承ContentProvider至少要重写六个方法,其中onCreate方法使用来初始化数据用的,一般用来初始化SqliteOpenHelper。剩下的就是对数据库的增删改查以及获取数据的mimeType。
既然疏导了SqliteOpenHelper,那么它是用来干什么的呢?SqliteOpenHelper从字面意义上来看就是数据库连接的工具,一般我们想要对操作android内部的数据库需要继承该类。
继承并实现SqliteOpenHelper
public class TestDatabaseHelper extends SQLiteOpenHelper {
public TestDatabaseHelper(Context context, String name, SQLiteDatabase.CursorFactory factory, int version) {
super(context, name, factory, version);
}
@Override
public void onCreate(SQLiteDatabase sqLiteDatabase) {
}
@Override
public void onUpgrade(SQLiteDatabase sqLiteDatabase, int oldVersion, int newVersion) {
}
}
需要实现onCreate和onUpgrade方法,其中onCreate是用来创建数据的,一般我们的数据的创建,各种表,视图的创建都是在该方法中实现的。onUpgrade是在数据库升级的时候调用的,通过构造方法传入不同的version可以来标明数据库的升级,在该方法中我们可以通过oldVersion和newVersion来进行比较,提示用户的升级,并且可以修改数据库。
Uri
讲了这么多,你可能会有疑问,那我们是怎样去调用呢?通过对ContentProvider的实现你可能已经发现了,对数据的增删改查都需要传入uri,这个uri就是关键。首先我们得了解一下Uri的构成。一般Uri的构成可以分为三个部分,scheme,authorities,path。
现在我们来用一个Uri来作为示例进行讲解吧
content://com.android.test.TestContentProvider/test/1
名称 | 示例 | 作用 |
---|---|---|
scheme | content:// | Android中已经规定了scheme为content:// |
authorities | com.android.test.TestContentProvider | 这个就是我们provider中定义的authorities |
path | test/1 | 要查询数据的表或者其id |
我们知道了Uri的构成,那么怎样去生成这样一个Uri呢?
Uri uri = Uri.prase("content://com.android.test.TestContentProvider/test");
这样我们就生成了一个uri,然后我们就可以通过ContentResolver就可以通过Uri来对数据库进行增删改查了。
Uri uri = Uri.prase("content://com.android.test.TestContentProvider/test");
ContentValues cv = new ContentValues();
//此处省略数据的添加 cv.add()...
getContentResolver().insert(uri,cv);
可能你又要问了,那系统怎么知道我们要查询的是哪个表,或者是哪个id呢?其实这中间还有一个关键的类没有说,那就是UriMatcher
UriMatcher就是用来匹配相应的uri,然后返回对应的code,以便用户进行操作。
我们来实际操作一下
首先需要在自定义ContentProvider中定义UriMatcher。
private static UriMatcher matcher = new UriMatcher(UriMatcher.NO_MATCH);
声明对应的常量,并进行addUri操作,addUri操作一般放在静态代码块中,这样在类的加载时可以完成uri的添加操作。
private static final Stirng AUTHORITY = "co.android.test.TestContentProvider";
private static final int TEST = 1;
static {
matcher.addUri(AUTHORITY,"test",TEST);
}
用户匹配Uri并进行处理。
switch (matcher.match(uri)) {
case TEST:
break;
default:
break;
}
注意
1.new UriMatcher中的参数一般选UriMatcher.NO_MATCH
2.addUri中三个参数分别代表的含义:AUTHORITY——provider的唯一标识,“test”——查询的表或者id(“test/#”——代表查询id),TEST——匹配成功后返回的code值
3.match匹配成功后返回的code值即是addUri中添加的第三个参数(例如上面例子中的TEST)
写到这里,关于ContentProvider的介绍就差不多了,你是否能写出自己的ContentProvider呢?