我在使用loadermanager时遇到了android内容提供程序的问题。我正在使用LoaderManager从ContentProvider加载我的CursorLoader,而ContentProvider正在调用我的sqlite类。 在Sqlite类中,我调用sql查询并返回游标,而不是关闭游标或数据库。 据我所知,它是如何工作的(当我关闭游标/数据库时它不起作用),但在第二次访问活动后,我得到关于数据库没有关闭的这个例外。它一定是蠢事。
我在我片段的onActivityCreated中调用了LoaderManager的initLoader。
这是我在ContentProvider中的查询方法:
public synchronized Cursor query(final Uri uri, final String[] projection, final String selection, final String[] selectionArgs, final String sortOrder) {
final SongDbHandler songDbHandler = AbstractActivity.getLocalService(getContext()).getDbHandler();
String order = " ";
if ("author".equals(sortOrder)) {
order = Constants.ORDER_AUTHOR;
} else if ("song".equals(sortOrder)) {
order = Constants.ORDER_SONG;
}
System.out.println("getAllSongs");
final Cursor cursor = songDbHandler.getAllSongs(order);
cursor.setNotificationUri(getContext().getContentResolver(), uri);
return cursor;
}
这是我在sqlite类中的代码(singleton SQLiteOpenHelper子类):
public Cursor getAllSongs(String order) {
SQLiteDatabase db = null;
Cursor cursor;
try {
db = this.getReadableDatabase();
String sql = "";
sql += "select " + Constants.AUTHOR_SELECT_COLUMNS + ", " + Constants.SONG_SELECT_COLUMNS + ", " + Constants.GLOBAL_ID;
sql += " from " + Constants.SONG_TABLE_NAME + ", " + Constants.AUTHOR_TABLE_NAME + " ";
sql += " where " + Constants.SONG_TABLE_NAME + "." + Constants.AUTHOR_FK + " = " + Constants.AUTHOR_TABLE_NAME + "." + Constants.AUTHOR_ID + " AND " + Constants.SONG_TABLE_NAME + "."
+ Constants.SONG_SOURCE_TYPE + " = " + Constants.AUTHOR_TABLE_NAME + "." + Constants.AUTHOR_SOURCE_TYPE;
// sql += " order by " + Constants.AUTHOR_TABLE_NAME + "." +
// Constants.AUTHOR_NAME + COLLATE;
sql += order;
// sql += " limit 20 ";
cursor = db.rawQuery(sql, new String[] {});
return cursor;
} finally {
//closeQuietly(db);
}
}
非常感谢任何帮助!
编辑: 这是我的LoaderManager回调:
@Override
public Loader<Cursor> onCreateLoader(int loaderId, Bundle bundle) {
return (Loader<Cursor>) new CursorLoader(getActivity().getApplicationContext(), SongContentProvider.getLocalProviderUri(), null, null, null, bundle.getString("order"));
}
@Override
public void onLoadFinished(Loader<Cursor> arg0, Cursor songs) {
updateData(songs);
}
@Override
public void onLoaderReset(Loader<Cursor> arg0) {
adapter.swapCursor(null);
}
EDIT2:
private void updateData(Cursor songs) {
adapter.swapCursor(songs);
if (songs == null || songs.getCount() == 0) {
vysledky.setVisibility(View.GONE);
vysledkyMsg.setText(getString(R.string.no_results));
vysledkyMsg.setVisibility(View.VISIBLE);
} else {
vysledky.setVisibility(View.VISIBLE);
vysledkyMsg.setText(getString(R.string.progress_loading_content));
vysledkyMsg.setVisibility(View.GONE);
}
}
答案 0 :(得分:0)
经过一段时间后,我终于解决了所有问题。最初导致错误,因为我的db类不是单例,并且每次调用都创建了新的数据库连接实例,因此旧的引用丢失了,而ContentProvder无法关闭它。基本上我来到这里:
现在我在3个片段中有3个并发的内容加载器,它们工作正常。