Note that there are some explanatory texts on larger screens.

plurals
  1. POAndroid ListView with SimpleCursorAdapter - Crashes onResume
    primarykey
    data
    text
    <p>I have a <code>ListView</code> in <code>AcitivityA</code> that is populated using a custom <code>SimpleCursorAdapter</code> called <code>RecipeAdapter</code>. The adapter holds data from <code>SQLite</code></p> <p>There is a <code>EditText</code> view at the top of the <code>ListView</code>, that filters the listview as the user searches for a recipe. When a user clicks on a item in the filtered <code>ListView</code>, <code>ActivityB</code> starts.</p> <p>This all works perfectly. However when the user presses the backbutton to resume <code>ActivityB</code>, I get the following error.</p> <pre><code>java.lang.IllegalStateException: trying to requery an already closed cursor android.database.sqlite.SQLiteCursor@418af170 </code></pre> <p>My attempts at fixing the problem:</p> <ul> <li>Duplicating code from the <code>onCreate()</code> to the <code>onResume</code> method.</li> <li>Adding <code>c.requery()</code> to <code>onResume()</code> method</li> <li>Adding <code>db.close</code> to <code>onDestroy()</code> method</li> </ul> <p>Can anyone help me with my problem?</p> <p>Here is my code:</p> <p>In the <code>onCreate</code>, the <code>cursor</code> populate the <code>ListView</code> using <code>c.getCursor</code> and when the user filters the <code>ListView</code> via the <code>EditText</code>, the <code>c.getFilterCursor</code> is used.</p> <pre><code>public class RecipeActivity extends SherlockListActivity { private DBHelper db = null; private Cursor c = null; private RecipeAdapter adapter = null; ListView listContent; private EditText filterText = null; @SuppressWarnings("deprecation") @Override public void onCreate(Bundle savedInstanceState) { try { super.onCreate(savedInstanceState); setContentView(R.layout.filter_list); filterText = (EditText) findViewById(R.id.search_box); filterText.addTextChangedListener(filterTextWatcher); ListView listContent = getListView(); db = new DBHelper(this); db.createDataBase(); db.openDataBase(); c = db.getCursor(); adapter = new RecipeAdapter(c); listContent.setAdapter(adapter); adapter.setFilterQueryProvider(new FilterQueryProvider() { public Cursor runQuery(CharSequence constraint) { // Search for states whose names begin with the specified letters. c = db.getFilterCursor(constraint); return c; } }); startManagingCursor(c); } catch (IOException e) { e.printStackTrace(); } } private TextWatcher filterTextWatcher = new TextWatcher() { public void afterTextChanged(Editable s) { } public void beforeTextChanged(CharSequence s, int start, int count, int after) { } public void onTextChanged(CharSequence s, int start, int before, int count) { adapter.getFilter().filter(s); } }; </code></pre> <p>RecipeAdapter inner class</p> <pre><code>class RecipeAdapter extends CursorAdapter { @SuppressWarnings("deprecation") public RecipeAdapter(Cursor c) { super(RecipeActivity.this, c); } public void bindView(View row, Context arg1, Cursor arg2) { RecipeHolder holder = (RecipeHolder) row.getTag(); holder.populateFrom(c, db); } public View newView(Context arg0, Cursor arg1, ViewGroup arg2) { LayoutInflater inflater = getLayoutInflater(); View row = inflater.inflate(R.layout.reciperow, arg2, false); RecipeHolder holder = new RecipeHolder(row); row.setTag(holder); return (row); } static class RecipeHolder { public TextView id = null; private TextView name = null; private TextView desc = null; private TextView preptime = null; private TextView cooktime = null; private TextView serves = null; private TextView calories = null; private TextView fat = null; private TextView fav = null; RecipeHolder(View row) { id = (TextView) row.findViewById(R.id.id); name = (TextView) row.findViewById(R.id.recipe); desc = (TextView) row.findViewById(R.id.desc); preptime = (TextView) row.findViewById(R.id.preptime); cooktime = (TextView) row.findViewById(R.id.cooktime); serves = (TextView) row.findViewById(R.id.serving); calories = (TextView) row.findViewById(R.id.calories); fat = (TextView) row.findViewById(R.id.fat); fav = (TextView) row.findViewById(R.id.fav); } void populateFrom(Cursor c, DBHelper r) { id.setText(r.getId(c)); name.setText(r.getRecipe(c)); name.setTextColor(Color.parseColor("#CCf27c22")); desc.setText(r.getDesc(c)); preptime.setText(r.getPrepTime(c) + ". "); cooktime.setText(r.getCookTime(c) + " mins"); serves.setText(r.getServes(c)); calories.setText(r.getCalories(c)); fat.setText(r.getFat(c)); fav.setText(r.getFav(c)); </code></pre> <p>getCursor() and getFilterCursor() code from DBHelper class</p> <pre><code>public Cursor getCursor() { SQLiteQueryBuilder queryBuilder = new SQLiteQueryBuilder(); queryBuilder.setTables(DATABASE_TABLE); String[] columns = new String[] { KEY_ROWID, RECIPE, DESC, PREPTIME, COOKTIME, SERVES, CALORIES, FAT, CATEGORY, FAV }; Cursor myCursor = queryBuilder.query(myDataBase, columns, null, null, null, null, RECIPE + " ASC"); return myCursor; } public Cursor getFilterCursor(CharSequence constraint) { SQLiteQueryBuilder queryBuilder = new SQLiteQueryBuilder(); queryBuilder.setTables(DATABASE_TABLE); String[] columns = new String[] { KEY_ROWID, RECIPE, DESC, PREPTIME, COOKTIME, SERVES, CALORIES, FAT, CATEGORY, FAV }; if (constraint == null || constraint.length() == 0) { // Return the full list return queryBuilder.query(myDataBase, columns, null, null, null, null, RECIPE + " ASC"); } else { String value = "%" + constraint.toString() + "%"; return myDataBase.query(DATABASE_TABLE, columns, "RECIPE like ? ", new String[] { value }, null, null, null); } } </code></pre> <p>FULL LOGCAT</p> <pre><code>FATAL EXCEPTION: main java.lang.RuntimeException: Unable to resume activity {ttj.android.quorn/ttj.android.quorn.RecipeActivity}: java.lang.IllegalStateException: trying to requery an already closed cursor android.database.sqlite.SQLiteCursor@41954658 at android.app.ActivityThread.performResumeActivity(ActivityThread.java:2456) at android.app.ActivityThread.handleResumeActivity(ActivityThread.java:2484) at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1185) at android.os.Handler.dispatchMessage(Handler.java:99) at android.os.Looper.loop(Looper.java:137) at android.app.ActivityThread.main(ActivityThread.java:4507) at java.lang.reflect.Method.invokeNative(Native Method) at java.lang.reflect.Method.invoke(Method.java:511) at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:790) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:557) at dalvik.system.NativeStart.main(Native Method) Caused by: java.lang.IllegalStateException: trying to requery an already closed cursor android.database.sqlite.SQLiteCursor@41954658 at android.app.Activity.performRestart(Activity.java:4508) at android.app.Activity.performResume(Activity.java:4531) at android.app.ActivityThread.performResumeActivity(ActivityThread.java:2446) </code></pre>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload