我在onLoadFinished回调(from LoaderManager.LoaderCallbacks)上返回了一个游标,我想对这个游标进行一些(可能是昂贵的)后处理.所以,我正在开火AsyncTask使用这个Cursor.但是,我遇到了这种异常的间歇性崩溃:
android.database.StaleDataException: Attempted to access a cursor after it has been closed.
Run Code Online (Sandbox Code Playgroud)
我怀疑这种情况正在发生,因为游标(由UI线程中的Loader管理)在后台线程完成之前正在关闭,因为这是一个托管游标.这是一些释义代码:
private class LoaderListener implements LoaderManager.LoaderCallbacks<Cursor> {
@Override
public void onCreateLoader(int d, Bundle args) {
return new CursorLoader(context, uri, projection, selection, selectionArgs, sortOrder);
}
@Override
public void onLoadFinished(Loader<Cursor> loader, Cursor cursor) {
processCursor(cursor)
}
}
private void processCursor(final Cursor cursor) {
new AsyncTask<Void, Void, Result> {
@Override
Result doInBackground(Void... params) {
while(cursor.isAfterLast() == false) {
// doing some costly things with cursor …Run Code Online (Sandbox Code Playgroud) 目前,我有一个装载机
@Override
public Loader<List<HomeMenuRowInfo>> onCreateLoader(int arg0, Bundle bundle) {
return new HomeMenuRowInfosLoader(this.getSherlockActivity());
}
Run Code Online (Sandbox Code Playgroud)
有时,由于内容更改,我需要让加载程序重新加载.我会做的.
this.getLoaderManager().getLoader(0).onContentChanged();
Run Code Online (Sandbox Code Playgroud)
但是,我希望onCreateLoader在内容更改时将一些其他捆绑信息传递给回调.我意识到通过使用onContentChanged,没有办法这样做.
我能搞清楚的唯一方法是
this.getLoaderManager().restartLoader(0, bundle, this);
Run Code Online (Sandbox Code Playgroud)
我想知道,是否有任何重大分歧Loader的行为,使用的restartLoader不是onContentChanged,除了捆绑传递的能力吗?
让我首先说这不是关于滚动ListViews的问题.我不想知道如何判断用户何时滚动到列表的底部,所以请不要给我这个问题的答案,或者将其标记为重复.
我正在使用一个扩展AsyncTaskLoader的类来使用来自Web服务的数据填充ListView.
最初,我加载50件物品,一切都很好.我需要知道如何告诉Loader以递增方式加载下50个项目.我理解在ListView代码中要执行此操作,但我无法找出告诉Loader我想要加载更多数据而不重置它并再次加载所有内容的最佳方法.
再说一次,澄清一下,我在这里要解决的问题只是通知加载器需要加载更多数据.它已经知道如何在第二次调用loadInBackground()时加载更多数据,并且ListView已经知道在何时/何时通知Loader,问题是如何.
一些相关代码:
@Override
public void onActivityCreated(Bundle savedInstanceState)
{
super.onActivityCreated(savedInstanceState);
m_adapter = new SearchAdapter(getActivity());
setListAdapter(m_adapter);
// if the loader doesn't already exist, one will be created
// otherwise the existing loader is reused so we don't have
// to worry about orientation and other configuration changes
getLoaderManager().initLoader(SEARCH_LOADER_ID, null, this);
}
@Override
public Loader<List<Result>> onCreateLoader(int id, Bundle args)
{
String query = args != null ? args.getString(QUERY_KEY) : "";
return new SearchLoader(getActivity(), query); …Run Code Online (Sandbox Code Playgroud) 我目前正在做一个项目,涉及根据我当前的位置显示附近的位置列表.
我不久前刚开始使用Android编程,所以在编码阶段我还在学习.
我搜索了所有试图得到一些关于如何继续的线索.阅读和尝试后我仍然被困住了.
我的工作代码目前包括
问题
过滤ListView条目的"正确"方法是什么?我在Filter/Filterable界面上看过帖子,但它似乎不适用于我当前的设置?我是否在Custom CursorAdapter中执行过滤?
执行过滤后,如何刷新ListView?我是否调用getLoaderManager().restartLoader(0,null,this)或adapter.notifyDataSetChanged()?
提前致谢.
android android-listview android-loadermanager android-cursorloader android-cursoradapter
我有两个加载器,一个用于填充绑定返回的数据到2 TextViews,另一个用于填充a ListView.如何确保为每种情况加载正确的装载程序?我在第一个加载器(WR_VIEWcase)似乎没有创建或加载的地方出现错误,因此onLoadFinished()它返回"没有这样的列发现错误",因为它正在访问不调用该列的第二个加载器.
在我的onCreate方法中,我为列表视图设置了适配器:
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.workouts_options);
String[] uiBindFrom = { ExerciseTable.COLUMN_NAME };
int[] uiBindTo = { R.id.text1 };
SimpleCursorAdapter adapter = new SimpleCursorAdapter(
getApplicationContext(),
R.layout.exercises_row,
null,
uiBindFrom,
uiBindTo,
CursorAdapter.FLAG_REGISTER_CONTENT_OBSERVER);
final ListView lv = (ListView) findViewById(android.R.id.list);
lv.setAdapter(adapter);
lv.setEmptyView(findViewById(android.R.id.empty));
lv.setClickable(true);
lv.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> arg0, View arg1, int position, long id) {
}
});
getSupportLoaderManager().initLoader(WR_VIEW, null, this);
getSupportLoaderManager().initLoader(EXERCISE_VIEW, null, this);
}
Run Code Online (Sandbox Code Playgroud)
创建我的2个不同的CursorLoaders:
public Loader<Cursor> …Run Code Online (Sandbox Code Playgroud) 希望简单的java问题我只是忘记或永远不会理解.我一直在玩Android 4.0中的Loaders.该计划正在按原样运作,但现在我正在寻找"下一个"部分.我想要一个标准的Cursor加载器和一个自定义的AsyncTaskLoader.我坚持第1部分试图将cursorLoader转换为Loader并返回它.
@Override
//public Loader<Cursor> onCreateLoader(int id, Bundle args) {
public Loader<Object> onCreateLoader(int id, Bundle args) {
if (id == LISTVIEWLOADER) {
String[] projection = { RunnerTable.COLUMN_ID,
RunnerTable.COLUMN_NAME };
CursorLoader cursorLoader = new CursorLoader(getActivity(),
FanContentProvider.CONTENT_URI, projection, null, null,
null);
return cursorLoader; //HERE IS THE PROBLEM
}
return null;
}
Run Code Online (Sandbox Code Playgroud)
类型不匹配无法从CursorLoader转换为Loader.
我相信可以使它合作
public class MainFragment extends ListFragment implements
//LoaderManager.LoaderCallbacks<Cursor>
LoaderManager.LoaderCallbacks
Run Code Online (Sandbox Code Playgroud)
但不喜欢警告:
LoaderManager.LoaderCallbacks是一种原始类型.应参数化对泛型类型LoaderManager.LoaderCallbacks的引用
感谢您提供的任何帮助.
我正在编写一个android示例应用程序,并尝试使用此处的示例代码创建listview示例.它无法解析LoaderManager.知道什么可能是错的吗?
我正在使用eclipse工具包和最新的android sdk.
我正在构建一个Android应用程序,它使用OSM数据为来自一组给定位置的用户提供路径.用户可以键入他们希望进入SearchView的位置,并且当用户键入搜索结果时,搜索结果将被缩小以缩小结果,然后他们可以从下拉ListView中选择目标.使用onQueryTextChange()完成此过滤.我正在使用ContentProvider从数据库中查询此数据并实现LoaderManager.LoaderCallbacks接口以重新查询ContentProvider并为要使用的适配器提供新数据.
所有这些都在绝大多数时间内完成,并且完全符合预期.但是,很少,应用程序将崩溃与以下堆栈跟踪.
java.lang.IllegalStateException: attempt to re-open an already-closed object: SQLiteQuery: SELECT _id, suggest_text_1, suggest_intent_data FROM Locations WHERE (suggest_text_1 LIKE ?)
at android.database.sqlite.SQLiteClosable.acquireReference(SQLiteClosable.java:55)
at android.database.sqlite.SQLiteQuery.fillWindow(SQLiteQuery.java:58)
at android.database.sqlite.SQLiteCursor.fillWindow(SQLiteCursor.java:152)
at android.database.sqlite.SQLiteCursor.onMove(SQLiteCursor.java:124)
at android.database.AbstractCursor.moveToPosition(AbstractCursor.java:214)
at android.database.CursorWrapper.moveToPosition(CursorWrapper.java:162)
at android.support.v4.widget.CursorAdapter.getItemId(CursorAdapter.java:225)
at android.widget.AdapterView.rememberSyncState(AdapterView.java:1195)
at android.widget.AdapterView$AdapterDataSetObserver.onChanged(AdapterView.java:811)
at android.widget.AbsListView$AdapterDataSetObserver.onChanged(AbsListView.java:6280)
at android.database.DataSetObservable.notifyChanged(DataSetObservable.java:37)
at android.widget.BaseAdapter.notifyDataSetChanged(BaseAdapter.java:50)
at android.support.v4.widget.CursorAdapter.swapCursor(CursorAdapter.java:347)
at android.support.v4.widget.SimpleCursorAdapter.swapCursor(SimpleCursorAdapter.java:326)
at android.support.v4.widget.CursorAdapter.changeCursor(CursorAdapter.java:315)
at android.support.v4.widget.CursorFilter.publishResults(CursorFilter.java:68)
at android.widget.Filter$ResultsHandler.handleMessage(Filter.java:282)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:136)
at android.app.ActivityThread.main(ActivityThread.java:5017)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:515)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:779)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:595)
at dalvik.system.NativeStart.main(Native Method)
Run Code Online (Sandbox Code Playgroud)
通常,当我清除SearchView以键入另一个搜索时会发生此错误,而其他时候会在用户键入时发生此错误.
编辑:包含部分ContentProvider,省略插入,删除和更新.
public class SearchContentProvider extends ContentProvider { …Run Code Online (Sandbox Code Playgroud) 我不明白所做的所有功能AsyncTaskLoader,例如onCancelLoad()和onForceLoad().所有功能及其调用顺序均未正确记录.
假设我想在后台下载文件并在需要时取消它.onCancelLoad()已经有了 什么目的cancelLoadInBackground().
android android-asynctask asynctaskloader android-loadermanager android-loader
我有一个内容提供程序,它返回query()方法的MatrixCursor.
Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder)
{
MatrixCursor cursor = new MatrixCursor(new String[]{"a","b"});
cursor.addRow(new Object[]{"a1","b1"});
return cursor;
}
Run Code Online (Sandbox Code Playgroud)
在LoaderManager的onLoadFinished()回调方法中,我使用游标数据来更新文本视图.
public void onLoadFinished(Loader<Cursor> cursorLoader, Cursor cursor) {
cursor.moveToFirst();
String text = (String) textView.getText();
while (!cursor.isAfterLast()) {
text += cursor.getString(1);
cursor.moveToNext();
}
textView.setText(text);
}
Run Code Online (Sandbox Code Playgroud)
现在的问题是,如何向MatrixCursor添加一个新行,它将立即通知对LoaderManager的回调方法的更改?
我希望,我已经明确了这个问题.提前致谢.
android android-contentprovider matrixcursor android-loadermanager