我对Android和Java一般不太熟悉,所以我的用语可能有误。对不起。
无论如何。我有一个ListActivity,它从LoaderManager获取数据。 LoaderManager使用ContentProvider https://github.com/jakenjarvis/Android-OrmLiteContentProvider。
使用contentUri(net.mydomain.app.listitems)获取数据时,一切运行良好,其定义方式与示例设置中的方式非常相似。但我需要来自连接查询的数据,并为该查询添加了一个URI(net.mydomain.app.listitems / items_joined)。 uri在Contract类中定义,并命名为itemsJoinedUri。使用此URI时,在将新数据插入表中时,视图中的列表不会更新。
在我的ContentProvider类的onQuery方法中,如果“模式代码”与itemsJoinedUri匹配,我会执行自定义查询。其他的恶习我把工作交给了超级方法。
public class DataProvider extends OrmLiteSimpleContentProvider<DatabaseHelper> {
@Override
protected Class<DatabaseHelper> getHelperClass() {
return DatabaseHelper.class;
}
@Override
public boolean onCreate() {
Controller = new MatcherController()
.add(ListItem.class, SubType.Directory, "", Contract.ListItem.CONTENT_URI_PATTERN_MANY)
.add(ListItem.class, SubType.Item, "#", Contract.ListItem.CONTENT_URI_PATTERN_ONE)
.add(ListItem.class, SubType.Directory, "items_joined", Contract.ListItem.CONTENT_URI_PATTERN_WITH_ITEMS_JOINED)
.initialize();
return true;
}
@Override
public Cursor onQuery(DatabaseHelper helper, MatcherPattern target, QueryParameters parameter) {
Cursor result = null;
//SQLiteQueryBuilder builder = new SQLiteQueryBuilder();
switch(target.getPatternCode()) {
case 310:
String MY_QUERY = "SELECT items.name as name, listitems._id as _id FROM listitems INNER JOIN items ON items._id = listitems.item_id WHERE list_id = ?";
SQLiteDatabase db = helper.getReadableDatabase();
result = db.rawQuery(MY_QUERY, parameter.getSelectionArgs());
break;
default:
result = super.onQuery(helper, target, parameter);
break;
}
return result;
}
}
相关部分的我的合同实施:
public class Contract {
public static final String DATABASE_NAME = "mydatabase.db";
public static final int DATABASE_VERSION = 1;
public static final String AUTHORITY = "net.mydomain.app";
.
.
.
public static class ListItem implements BaseColumns {
public static final String TABLENAME = "listitems";
public static final String CONTENT_URI_PATH = TABLENAME;
public static final String MIMETYPE_TYPE = TABLENAME;
public static final String MIMETYPE_NAME = AUTHORITY + ".provider";
// field info
public static final String ITEM = "item_id";
public static final String LIST = "list_id";
public static final String QUANTITY = "quantity";
// content uri pattern code
public static final int CONTENT_URI_PATTERN_MANY = 300;
public static final int CONTENT_URI_PATTERN_ONE = 301;
public static final int CONTENT_URI_PATTERN_WITH_ITEMS_JOINED = 310;
// Refer to activity.
public static final Uri contentUri = new Uri.Builder()
.scheme(ContentResolver.SCHEME_CONTENT)
.authority(AUTHORITY)
.appendPath(CONTENT_URI_PATH)
.build();
public static final Uri itemsJoinedUri = new Uri.Builder()
.scheme(ContentResolver.SCHEME_CONTENT)
.authority(AUTHORITY)
.appendPath(CONTENT_URI_PATH)
.appendPath("items_joined")
.build();
}
}
ListActivity的onCreateLoader方法在这里。我想使用但没有正确更新列表的那个被注释掉了。
// @Override
// public Loader<Cursor> onCreateLoader(int id, Bundle bundle) {
// String[] selectArgs = { "" + list_id };
// Uri baseUri = Contract.ListItem.itemsJoinedUri;
// return new CursorLoader(this, baseUri, null, null, selectArgs, null);
// }
@Override
public Loader<Cursor> onCreateLoader(int id, Bundle bundle) {
String select = "( " + Contract.ListItem.LIST + " = 2 )";
Uri baseUri = Contract.ListItem.contentUri;
String[] projection = new String[] {
Contract.ListItem._ID,
Contract.ListItem.LIST
};
return new CursorLoader(this, baseUri, projection, select, null, null);
}
使用代码getContentResolver().insert(Contract.ListItem.contentUri, values);
将列表中的新项目插入到不同的活动中。该活动在层次结构中比ListActivity更深一点,所以我可以使用后退按钮返回ListActivity,这就是当我看到列表没有更新时。
所以使用contentUri插入数据,但使用我自己的itemsJoinedUri读取。这可能是问题吗?
修改
我添加了一个简单的clicklistener来从列表中删除一行。这使用contentUri,删除后列表会自动更新。所以我想当从另一个Activity移回列表时列表没有被更新的问题可能与ListActivity的生命周期的错误实现有关。
@Override
public void onListItemClick(ListView l, View v, int position, long id) {
String[] args = { "" + id};
getContentResolver().delete(Contract.ListItem.contentUri, "_id = ?", args);
}
答案 0 :(得分:1)
问题出在生命周期管理上。我没有适当的onRestart()实现。添加后,一切正常。
@Override
public void onRestart() {
super.onRestart();
getLoaderManager().getLoader(0).forceLoad();
}
答案 1 :(得分:0)
在您注释掉的部分中,您只发送选择参数但不发送选择字符串。选择参数不能单独使用,您还必须设置选择字符串,例如:
return new CursorLoader(this, baseUri, null, "_id = ?", selectArgs, null);
这有用吗?