Cursor finalizado sin cerrar antes () en ListFragment
Estoy recibiendo este mensaje de error después de cerrar la aplicación o simplemente dejar que el teléfono de dormir con la aplicación abierta.
Cuando dejo el teléfono dormir, consigo 30 a 61 entradas de registro de este mensaje de error. El error se registra justo antes de que se carga el ListFragment. Sospecho que el fragmento se carga pero el error se registra antes de las entradas de información del fragmento.
- ¿Cómo puedo mantener mi base de datos en una tarjeta SD y utilizar ORMLite?
- Acceso y almacenamiento de gran cantidad de datos desde el servidor mysql
- Actualizar la tabla sqlite en android
- Insertar o actualizar en SQlite y Android utilizando la base de datos.query ();
- Cambiar el número de versión de la base de datos SQLite
Cuando cierro la aplicación, sólo obtengo 1 entrada del error que se registra justo después de la llamada onLoaderReset (). Cierro la base de datos antes de cerrar la aplicación que aparece para ayudar.
La aplicación funciona, pero me preocupa que fallará una vez que se ejecuta en una variedad de teléfonos.
No controlo explícitamente el cursor excepto para adapter.swapCursor (null) en onLoaderReset ().
Agradezco cualquier idea sobre cómo resolver este error.
Gracias
public class ChildList extends ListFragment implements LoaderManager.LoaderCallbacks<Cursor>, DatabaseConstants, GoodiList { private final String TAG = "ChildList"; // database columns that we will retreive final String[] PROJECTION = new String[] { CHILD_ID_COLUMN, CHILD_NAME_COLUMN }; // selects all final String SELECTION = null; SimpleCursorAdapter adapter = null; private ListParent parentActivity; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); Log.e(TAG, "on Create"); String[] fromColumns = { CHILD_NAME_COLUMN, CHILD_ID_COLUMN }; int[] toViews = { R.id.name_column, R.id.id_column }; adapter=new SimpleCursorAdapter( getActivity(), R.layout.child_list_entry, null, fromColumns, toViews, 0 ); setListAdapter(adapter); getLoaderManager().initLoader(0, null, this); Log.i(TAG, "finished on Create"); } public void onActivityCreated(Bundle savedInstanceState) { super.onActivityCreated(savedInstanceState); LongClickListener longClickListener = new LongClickListener(); getListView().setOnItemLongClickListener(longClickListener); } @Override public void setListAdapter(ListAdapter adapter) { super.setListAdapter(adapter); } @Override public Loader<Cursor> onCreateLoader(int arg0, Bundle arg1) { Log.v(TAG, "starting on create loader"); Uri CHILD_URI = ChildContentProvider.CONTENT_URI; CursorLoader cursorLoader = new CursorLoader(getActivity(), CHILD_URI, PROJECTION, SELECTION, null, null); Log.v(TAG, "finished on create loader"); return cursorLoader; } @Override public void onLoadFinished(Loader<Cursor> arg0, Cursor newCursor) { adapter.swapCursor(newCursor); if (newCursor != null) { int rowCount = newCursor.getCount(); Log.v(TAG, "--- onLoadFinished: got " + rowCount + " children"); } } /** * this used to delete. However, we need it to select usually. Now delete is * done by long click. */ @Override public void onListItemClick(ListView l, View v, int position, long id) { super.onListItemClick(l, v, position, id); // delete child - remove child from list and database Object item = l.getItemAtPosition(position); Cursor cursor = (Cursor) item; int nameCol = cursor.getColumnIndex(CHILD_NAME_COLUMN); int idCol = cursor.getColumnIndex(CHILD_ID_COLUMN); final String name = cursor.getString(nameCol); final int childId = cursor.getInt(idCol); Log.i(TAG, "selected " + name + " id: " + childId + " at position " + position); cursor.close(); parentActivity.listItemSelected(this, position, childId); } /** * Forces cursor to requery database and list to be update. Used when a new * child is entered in parent activity's EditText field. */ public void notifyDataChanged() { Log.i(TAG, "told adapter that data changed"); getLoaderManager().restartLoader(0, null, this); adapter.notifyDataSetChanged(); } /** tell adapter that cursor is no longer valid*/ @Override public void onLoaderReset(Loader<Cursor> arg0) { Log.i(TAG,"---- onLoaderReset -----"); adapter.swapCursor(null); } @Override public void onAttach(Activity activity) { super.onAttach(activity); parentActivity = (ListParent) activity; parentActivity.setList(this); }
- IllegalArgumentException: columna no válida
- Recuperar una lista de todas las tablas de la base de datos
- No se puede usar como cláusula en la aplicación android
- SQLite de SQL INSERT o REPLACE
- Seleccione sólo los descendientes directos de la tabla con una ruta materializada
- Visibilidad de variables en SQLiteOpenHelper android
- Cómo almacenar JSON en SQLite
- SQLite Transformar columnas en cadena delimitada por comas
Tuve el mismo problema, y lo resolví tomando un vistazo a la documentación.
De acuerdo con los documentos, http://developer.android.com/reference/android/widget/CursorAdapter.html#swapCursor(android.database.Cursor)
el método swapCursor(Cursor data)
devuelve el cursor original no cerrado. Si el nuevo cursor es el mismo que el anterior o si no hay un antiguo, devuelve nulo.
Cambiando mi código de
@Override public void onLoadFinished(Loader<Cursor> loader, Cursor data) { adapter.swapCursor(data); }
a
@Override public void onLoadFinished(Loader<Cursor> loader, Cursor data) { Cursor cursor = adapter.swapCursor(data); if (cursor != null) { cursor.close(); } }
Paré estas advertencias de aparecer.
Nota: Debe hacer lo mismo con el método onLoaderReset()
. Para incluso cuando hace adapter.swapCursor(null)
, devuelve el cursor antiguo.
- Cómo grabar la pantalla de actividad de la webview con Android MediaCodec?
- onPostExecute () no funciona en volver a ejecutar de asyncTask llamado de una actividad