我正在阅读this tutorial关于实现我自己的ContentProvide以使用SQLite。在ContentProvider.query中有一些让我感到困惑的事情。它似乎非常硬编码只有一个表(教程中的待办事项表),但也许我只是没有得到它?现在如果我想查询另一个表,让我们说nodo,我将如何更改ContentProvider?
我应该在queryBuilder.setTables(String inTables)中以某种方式附加表名吗?
如果每个表都有一个CONTENT_TYPE和CONTENT_ITEM_TYPE怎么办?
关于TODO和TODO_ID varibles以及查询方法中的开关?
似乎我需要有很多if / switch条件来支持具有相同ContentProvider的多个表,这是要走的路还是我在错误的路径上?
谢谢
索伦
答案 0 :(得分:27)
现在,如果我想查询另一个表,请说nodo,我将如何更改ContentProvider?
查询新表意味着您需要添加新的Uri
,因为Uri
选择了数据源,类似于使用不同的表。
您将基本上添加已存在的其他表的待办事项的所有硬编码值。例如:
// ------- usually the same for all
private static final String AUTHORITY = "de.vogella.android.todos.contentprovider";
// ------- define some Uris
private static final String PATH_TODOS = "todos";
private static final String PATH_REMINDERS = "reminders";
public static final Uri CONTENT_URI_TODOS = Uri.parse("content://" + AUTHORITY
+ "/" + PATH_TODOS);
public static final Uri CONTENT_URI_REMINDERS = Uri.parse("content://" + AUTHORITY
+ "/" + PATH_REMINDERS);
// ------- maybe also define CONTENT_TYPE for each
// ------- setup UriMatcher
private static final int TODOS = 10;
private static final int TODO_ID = 20;
private static final int REMINDERS = 30;
private static final int REMINDERS_ID = 40;
private static final UriMatcher sURIMatcher = new UriMatcher(UriMatcher.NO_MATCH);
static {
sURIMatcher.addURI(AUTHORITY, PATH_TODOS, TODOS);
sURIMatcher.addURI(AUTHORITY, PATH_TODOS + "/#", TODO_ID);
sURIMatcher.addURI(AUTHORITY, PATH_REMINDERS, REMINDERS);
sURIMatcher.addURI(AUTHORITY, PATH_REMINDERS + "/#", REMINDERS_ID);
}
//@Override
public Cursor query(Uri uri, String[] projection, String selection,
String[] selectionArgs, String sortOrder) {
// Using SQLiteQueryBuilder instead of query() method
SQLiteQueryBuilder queryBuilder = new SQLiteQueryBuilder();
int uriType = sURIMatcher.match(uri);
switch (uriType) {
case TODO_ID:
// Adding the ID to the original query
queryBuilder.appendWhere(TodoTable.COLUMN_ID + "="
+ uri.getLastPathSegment());
//$FALL-THROUGH$
case TODOS:
queryBuilder.setTables(TodoTable.TABLE_TODO);
break;
case REMINDERS_ID:
// Adding the ID to the original query
queryBuilder.appendWhere(ReminderTable.COLUMN_ID + "="
+ uri.getLastPathSegment());
//$FALL-THROUGH$
case REMINDERS:
queryBuilder.setTables(ReminderTable.TABLE_REMINDER);
break;
default:
throw new IllegalArgumentException("Unknown URI: " + uri);
}
我应该在queryBuilder.setTables(String inTables)中以某种方式附加表名吗?
是的,如果从不同的表中读取不同的Uri
,则根据Uri匹配设置表。
如果每个表都有一个CONTENT_TYPE和CONTENT_ITEM_TYPE怎么办?
取决于实际的内容类型。如果它们不同并且您需要类型是。但你根本不需要它们。该示例定义了它们,但甚至没有使用它们。它需要返回getType
中的类型,请参阅documentation。
关于TODO和TODO_ID varibles以及查询方法中的开关?
这些是为UriMatcher
定义的常量,可以很好地解释here。它基本上是字符串匹配的简化。一个大的ContentProvider
可以拥有100个不同的Uris,如果你必须一直写query
,那么在if (uri.getPath().equals("todos") { /* code */ } else if (uri..
中选择正确的表会很痛苦。
答案 1 :(得分:1)
以下是solution您的问题,使用UriMatcher,您可以在内容提供商中实现多个表。
答案 2 :(得分:0)
内容类型和内容项可以如下所示,它们可以包装在每个表的单独类中
public static final String GENERAL_CONTENT_TYPE = "vnd.android.cursor.dir/vnd.myfirstapp.db.member" ;
public static final String SPECIFIC_CONTENT_TYPE = "vnd.android.cursor.item/vnd.myfirstapp.db.member" ;
`vnd.android.cursor.dir / vnd.yourownanything.anything.tablename'
这定义了一般内容类型 `vnd.android.cursor.item / vnd.anthingasabove.table” 这也定义了特定的,它对任何应用程序都是常量,那些字符串(单词)vnd.android.cursor.dir和.item必须和/ vnd之后一样。必须像那样
并且在扩展contentprovider的类中,您只需使用相同的UriMatcher实例来映射表