我在读关于实施我自己ContentProvide与SQLite的工作本教程。诠释了ContentProvider.query有几件事令我费解。这似乎很难coded到只有一个表(本教程中的待办事项表),但也许我只是没有得到它?现在,如果我想查询另一个表,可以说NODO,我将如何改变ContentProvider的?
我应该在queryBuilder.setTables(字符串inTables)莫名其妙地追加表名称?
怎么样的CONTENT_TYPE和CONTENT_ITEM_TYPE,应该有一个用于每个表?
这对TODO和TODO_ID可变因素和查询方法开关?
看来我需要有很多,如果/开关条件,支持具有相同的ContentProvider多个表的,这是要走的路还是我在错误的道路?
感谢您 瑟伦
解决方案现在,如果我想查询另一个表,可以说NODO,我将如何改变ContentProvider的?
查询新表就意味着你需要添加一个新的乌里
,因为乌里
选择数据源类似于使用不同的表
您将加入基本上所有的硬codeD中已经存在的待办事项为你的其他表值。例如:
// -------通常是相同的所有
私有静态最后弦乐管理局=de.vogella.android.todos.contentprovider;
// -------定义一些尤里斯
私有静态最后弦乐PATH_TODOS =待办事项;
私有静态最后弦乐PATH_REMINDERS =提醒;
公共静态最终乌里CONTENT_URI_TODOS = Uri.parse(内容://+ AUTHORITY
+/+ PATH_TODOS);
公共静态最终乌里CONTENT_URI_REMINDERS = Uri.parse(内容://+ AUTHORITY
+/+ PATH_REMINDERS);
// -------也许还定义CONTENT_TYPE每个
// -------设置UriMatcher
私有静态最终诠释TODOS = 10;
私有静态最终诠释TODO_ID = 20;
私有静态最终诠释事项注= 30;
私有静态最终诠释REMINDERS_ID = 40;
私有静态最后UriMatcher sURIMatcher =新UriMatcher(UriMatcher.NO_MATCH);
静态{
sURIMatcher.addURI(权威,PATH_TODOS,TODOS);
sURIMatcher.addURI(权威,PATH_TODOS +/#,TODO_ID);
sURIMatcher.addURI(权威,PATH_REMINDERS,提醒);
sURIMatcher.addURI(权威,PATH_REMINDERS +/#,REMINDERS_ID);
}
// @覆盖
公共光标查询(URI URI,字符串[]投影,串选择,
的String [] selectionArgs两个,串排序顺序){
//使用SQLiteQueryBuilder而不是query()方法
SQLiteQueryBuilder QueryBuilder的=新SQLiteQueryBuilder();
INT uriType = sURIMatcher.match(URI);
开关(uriType){
案例TODO_ID:
//添加ID发送给原始查询
queryBuilder.appendWhere(TodoTable.COLUMN_ID +=
+ uri.getLastPathSegment());
// $落空$
案例TODOS:
queryBuilder.setTables(TodoTable.TABLE_TODO);
打破;
案例REMINDERS_ID:
//添加ID发送给原始查询
queryBuilder.appendWhere(ReminderTable.COLUMN_ID +=
+ uri.getLastPathSegment());
// $落空$
案件提点:
queryBuilder.setTables(ReminderTable.TABLE_REMINDER);
打破;
默认:
抛出新抛出:IllegalArgumentException(未知URI:+ URI);
}
我应该在queryBuilder.setTables(字符串inTables)莫名其妙地追加表名称?
是的,如果不同的乌里
■从不同的表中读取,然后基于URI匹配表中设置。
怎么样的CONTENT_TYPE和CONTENT_ITEM_TYPE,应该有一个用于每个表?
取决于实际内容类型。如果它们是不同的,你需要一个类型是的。但你并不需要他们的。这个例子定义了他们,但甚至不使用它们。这将需要返回类型的getType
,见documentation.
这对TODO和TODO_ID可变因素和查询方法开关?
这些都是为 UriMatcher
这是很好解释的此处。这基本上是一个简化的字符串相匹配。一个大的的ContentProvider
可以有100个不同的URI和查询选择合适的表
将是痛苦的,如果你会写如果(uri.getPath()。等于(待办事项){/ * code * /}否则,如果(URI ..
一路。
I am reading this tutorial on implementing my own ContentProvide for working with SQLite. Int the ContentProvider.query there are a few thing that puzzles me. It seems very hardcoded to just one table (the todo table in the tutorial), but maybe Im just not getting it? Now if I wanted to query another table, lets say nodo, how would I change the ContentProvider?
Should I append the table names somehow in queryBuilder.setTables(String inTables)?
What about the CONTENT_TYPE and CONTENT_ITEM_TYPE, should there be one for each table?
That about the TODO and TODO_ID varibles and the switch in the query method?
It seems I need to have a lot of if/switch conditions to support multiple tables with the same ContentProvider, is this the way to go or am I on a wrong path?
Thank you Søren
解决方案Now if I wanted to query another table, lets say nodo, how would I change the ContentProvider?
Querying a new table would mean that you need to add a new Uri
, since the Uri
selects the datasource, similar to using a different table.
You would be adding essentially all the hardcoded values that are already there for the todos for your other table. For example:
// ------- 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);
}
Should I append the table names somehow in queryBuilder.setTables(String inTables)?
Yes, if different Uri
s read from different tables then set the table based on the Uri match.
What about the CONTENT_TYPE and CONTENT_ITEM_TYPE, should there be one for each table?
Depends on the actual content type. If they are different and you need a type yes. But you don't need to have them at all. That example defines them but doesn't even use them. It would need to return the type in getType
, see documentation.
That about the TODO and TODO_ID varibles and the switch in the query method?
Those are constants defined for the UriMatcher
which is explained nicely here. It's basically a simplification for String matching. A big ContentProvider
can have 100 different Uris and selecting the right table in query
would be painful if you would have to write if (uri.getPath().equals("todos") { /* code */ } else if (uri..
all the way.
上一篇:如何在web视图使用iframe来播放VIMEO视频?视图、如何在、视频、web
下一篇:在谷歌Play应用中,ViewGroup中是如何显示的应用程序列表顶部实施?应用程序、列表、Play、ViewGroup