Android的 - 试图重新打开一个已关闭的对象:使用loaderManager SQLiteQuery [英] Android - attempt to re-open an already-closed object: SQLiteQuery using loaderManager

本文介绍了Android的 - 试图重新打开一个已关闭的对象:使用loaderManager SQLiteQuery的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我是相当新的Andr​​oid和我有一些问题与过滤ListView和它在从横向模式更改为纵向模式或反之亦然活动。我有我使用的过滤drinkSearch一个EditText,只要我不改变视角(纵向横向VS),这种过滤工作。这是我的错误:

I am fairly new to android and I have some problems with a filtered listView and The activity it's in changing from landscape mode to portrait mode or or vice versa. I have an editText that I use for filtering "drinkSearch", this filtering works as long as I do not change the viewing angle (portrait vs landscape). This is the error that I get:

java.lang.IllegalStateException:尝试重新打开一个已关闭
  对象:SQLiteQuery:SELECT _id,名字从饮料

java.lang.IllegalStateException: attempt to re-open an already-closed object: SQLiteQuery: SELECT _id, name FROM drinks

你可以在以下code我使用的接口LoaderManager.LoaderCallbacks看到,这个概念对我来说还挺新的,我不知道
哪里出问题。我想AP preciate所有帮助,在此先感谢!

As you can see in the following code I use the interface LoaderManager.LoaderCallbacks, this concept is kinda new for me and I am not sure where things go wrong. I would appreciate all help, thanks in advance!

公共类Drinks_Fragment扩展片段实现LoaderManager.LoaderCallbacks {

public class Drinks_Fragment extends Fragment implements LoaderManager.LoaderCallbacks {

private static final int DRINKS_LIST_LOADER = 0x01;
private SimpleCursorAdapter adapter;
private ListView drinksList;
private String LOG;
private EditText drinkSearch;

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {

    View view = inflater.inflate(R.layout.drinks_list, container, false);
    drinkSearch = (EditText)view.findViewById(R.id.drinkInputSearch);
    drinksList = (ListView) view.findViewById(R.id.drinksList);
    drinksList.setEmptyView(view.findViewById(R.id.empty_list_view));

    String[] from = {DrinksTable.COLUMN_NAME};
    int[] to = {R.id.drinkName};
    getLoaderManager().initLoader(DRINKS_LIST_LOADER, null, this);
    adapter = new SimpleCursorAdapter(getActivity().getApplicationContext(), R.layout.drinks_list_item,null, from, to, 0);
    drinksList.setAdapter(adapter);

在这一部分,我问我的ContentProvider基于在searchDrink EDITTEXT输入的字符串一个新的光标。 (继code,直到返回查看只是以上的部分,同样的方法onCreateView下文)

In this part I ask my contentProvider for a new Cursor based on the string entered in the searchDrink editText. (Following code, until "return view" is just below the part above, same onCreateView method)

    drinkSearch.addTextChangedListener(new TextWatcher() {

        @Override
        public void onTextChanged(CharSequence s, int arg1, int arg2, int arg3) {
            // When user changed the Text
            adapter.getFilter().filter(s.toString());
        }

        @Override
        public void beforeTextChanged(CharSequence arg0, int arg1, int arg2, int arg3) {
            // TODO Auto-generated method stub

        }

        @Override
        public void afterTextChanged(Editable arg0) {
            // TODO Auto-generated method stub
        }
    });

    adapter.setFilterQueryProvider(new FilterQueryProvider() {

        public Cursor runQuery(CharSequence constraint) {
            String value = "%"+constraint.toString()+"%";
            ContentResolver content = getActivity().getContentResolver();
            return content.query(CupProvider.DRINKS_URI,new String[]{DrinksTable.COLUMN_ID,DrinksTable.COLUMN_NAME},DrinksTable.COLUMN_NAME + " LIKE ?",new String[]{value},null);
        }
    });

    return view;
}

@Override
public void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) {
    super.onCreateContextMenu(menu,v,menuInfo);
    MenuInflater inflater = getActivity().getMenuInflater();
    inflater.inflate(R.menu.drink_actions,menu);
}


@Override
public Loader<Cursor> onCreateLoader(int i, Bundle bundle) {
    String[] projection = {DrinksTable.COLUMN_ID, DrinksTable.COLUMN_NAME};
    CursorLoader cursorLoader = new CursorLoader(getActivity(), CupProvider.DRINKS_URI, projection, null, null, null);
    return cursorLoader;
}

@Override
public void onLoadFinished(Loader<Cursor> cursorLoader, Cursor cursor) {
    adapter.swapCursor(cursor);

}

@Override
public void onLoaderReset(Loader<Cursor> cursorLoader) {
    // data is not available anymore, delete reference
    adapter.swapCursor(null);
}

}

这里有两个画面,展示它的外观的时刻: http://oi42.tinypic.com /dfc702.jpg
http://oi43.tinypic.com/2ylqkqa.jpg

Here are 2 pictures to show how it looks at the moment: http://oi42.tinypic.com/dfc702.jpg http://oi43.tinypic.com/2ylqkqa.jpg

推荐答案

您code是有点难以做出应有意识差格式。

Your code is a bit hard to make sense of due to poor formatting.

总之,所提供的答案其实并不是一个修复。在 onLoadFinished 返回光标应保证不会被关闭,所以你加载你的光标在错误的方式。特别是,当你调用

Anyway, the supplied answer is actually not a fix. The cursor returned at onLoadFinished should be guaranteed not to be closed, so you're loading your cursor in the wrong manner. Specifically, when you call

adapter.getFilter()过滤器(s.toString());

我真的不明白发生的事情在这里,但我明白,你应该做别的事情。刚刚查询过滤器存放在一个领域你的片段中及运行 getLoaderManager()restartLoader(DRINKS_LIST_LOADER,null,则此); 。请注意,您运行 restartLoader ,而不是 initLoader ,因为你要查询不同的数据。

I don't really understand what goes on here, but I do understand that you should do something else. Just store the query filter in a field within your Fragment and run getLoaderManager().restartLoader(DRINKS_LIST_LOADER, null, this);. Note that you run restartLoader, and not initLoader, because you have different data that you want to query for.

在你的 onCreateLoader ,你应该用你作为选择一个实例变量存储过滤器

In your onCreateLoader, you should use the filter that you stored as an instance variable for the selection.

initLoader 加载已加载的最后运行,如果它之前运行数据。这就是为什么你在你的片段/活动的初始化方法来访。这是方便,因为你不会有重新查询的方向改变。

initLoader loads the data that was loaded in the last run, if it had run before. This is why you call in in the initialization method of your Fragment/Activity. This is handy because you won't have to requery on orientation change.

restartLoader 清理previously加载的数据,让你得到一个新的装载机与(可能)不同的数据。

restartLoader cleans up previously loaded data so that you get a new Loader to work with (likely) different data.

如果你真的不知道自己在做什么还,请务必阅读这篇文章,这与样品code装载机很好的介绍性文章,看起来非常像你想达到什么目的。装载机是pretty起初神秘,但一旦你得到了它的窍门是一帆风顺。

If you aren't really sure what you're doing still, make sure to read this article, which is a very good introductory article on Loaders with sample code that looks very much like what you want to achieve. Loaders are pretty enigmatic at first, but once you get the hang of it it's smooth sailing.

这篇关于Android的 - 试图重新打开一个已关闭的对象:使用loaderManager SQLiteQuery的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆