Cerrar () nunca se llamó explícitamente en base de datos incluso después de implementar close ()

Eclipse me está mostrando el error anterior, aunque he implementado el dicho methos close ().

Aquí está el código:

public void update_project(View view) { EditText cinone = (EditText) findViewById(R.id.pname); pname = cinone.getText().toString(); String fDate = pday + ". " + pmonth + ". " + pyear; projectdatabase dbupdate = new projectdatabase(UpdateProject.this); dbupdate.open(); dbupdate.updateProject(id, pname, fDate); dbupdate.close(); } 

Logcat:

 12-31 22:05:51.114: E/SQLiteDatabase(4180): close() was never explicitly called on database '/data/data/com.kk.project/databases/project_db' 12-31 22:05:51.114: E/SQLiteDatabase(4180): android.database.sqlite.DatabaseObjectNotClosedException: Application did not close the cursor or database object that was opened here 12-31 22:05:51.114: E/SQLiteDatabase(4180): at android.database.sqlite.SQLiteDatabase.<init>(SQLiteDatabase.java:1943) 12-31 22:05:51.114: E/SQLiteDatabase(4180): at android.database.sqlite.SQLiteDatabase.openDatabase(SQLiteDatabase.java:1007) 12-31 22:05:51.114: E/SQLiteDatabase(4180): at android.database.sqlite.SQLiteDatabase.openDatabase(SQLiteDatabase.java:986) 12-31 22:05:51.114: E/SQLiteDatabase(4180): at android.database.sqlite.SQLiteDatabase.openOrCreateDatabase(SQLiteDatabase.java:1051) 12-31 22:05:51.114: E/SQLiteDatabase(4180): at android.app.ContextImpl.openOrCreateDatabase(ContextImpl.java:770) 12-31 22:05:51.114: E/SQLiteDatabase(4180): at android.content.ContextWrapper.openOrCreateDatabase(ContextWrapper.java:221) 12-31 22:05:51.114: E/SQLiteDatabase(4180): at android.database.sqlite.SQLiteOpenHelper.getWritableDatabase(SQLiteOpenHelper.java:157) 12-31 22:05:51.114: E/SQLiteDatabase(4180): at com.kk.project.projectdatabase.open(projectdatabase.java:66) 12-31 22:05:51.114: E/SQLiteDatabase(4180): at com.kk.project.ProjectExplorer.getinfo(ProjectExplorer.java:30) 12-31 22:05:51.114: E/SQLiteDatabase(4180): at com.kk.project.ProjectExplorer.onCreate(ProjectExplorer.java:25) 12-31 22:05:51.114: E/SQLiteDatabase(4180): at android.app.Activity.performCreate(Activity.java:4465) 12-31 22:05:51.114: E/SQLiteDatabase(4180): at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1049) 12-31 22:05:51.114: E/SQLiteDatabase(4180): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1920) 12-31 22:05:51.114: E/SQLiteDatabase(4180): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1981) 12-31 22:05:51.114: E/SQLiteDatabase(4180): at android.app.ActivityThread.access$600(ActivityThread.java:123) 12-31 22:05:51.114: E/SQLiteDatabase(4180): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1147) 12-31 22:05:51.114: E/SQLiteDatabase(4180): at android.os.Handler.dispatchMessage(Handler.java:99) 12-31 22:05:51.114: E/SQLiteDatabase(4180): at android.os.Looper.loop(Looper.java:137) 12-31 22:05:51.114: E/SQLiteDatabase(4180): at android.app.ActivityThread.main(ActivityThread.java:4424) 12-31 22:05:51.114: E/SQLiteDatabase(4180): at java.lang.reflect.Method.invokeNative(Native Method) 12-31 22:05:51.114: E/SQLiteDatabase(4180): at java.lang.reflect.Method.invoke(Method.java:511) 12-31 22:05:51.114: E/SQLiteDatabase(4180): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:784) 12-31 22:05:51.114: E/SQLiteDatabase(4180): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:551) 12-31 22:05:51.114: E/SQLiteDatabase(4180): at dalvik.system.NativeStart.main(Native Method) 12-31 22:05:51.165: E/System(4180): Uncaught exception thrown by finalizer 12-31 22:05:51.174: D/dalvikvm(4180): GREF has increased to 201 12-31 22:05:51.204: I/dalvikvm(4180): threadid=3: reacting to signal 3 12-31 22:05:51.324: E/System(4180): java.lang.IllegalStateException: Don't have database lock! 12-31 22:05:51.324: E/System(4180): at android.database.sqlite.SQLiteDatabase.verifyLockOwner(SQLiteDatabase.java:2090) 12-31 22:05:51.324: E/System(4180): at android.database.sqlite.SQLiteDatabase$1.entryRemoved(SQLiteDatabase.java:2182) 12-31 22:05:51.324: E/System(4180): at android.database.sqlite.SQLiteDatabase$1.entryRemoved(SQLiteDatabase.java:2178) 12-31 22:05:51.324: E/System(4180): at android.util.LruCache.trimToSize(LruCache.java:197) 12-31 22:05:51.324: E/System(4180): at android.util.LruCache.evictAll(LruCache.java:285) 12-31 22:05:51.324: E/System(4180): at android.database.sqlite.SQLiteDatabase.deallocCachedSqlStatements (SQLiteDatabase.java:2143) 12-31 22:05:51.324: E/System(4180): at android.database.sqlite.SQLiteDatabase.closeClosable(SQLiteDatabase.java:1126) 12-31 22:05:51.324: E/System(4180): at android.database.sqlite.SQLiteDatabase.finalize(SQLiteDatabase.java:1914) 12-31 22:05:51.324: E/System(4180): at java.lang.Daemons$FinalizerDaemon.doFinalize(Daemons.java:182) 12-31 22:05:51.324: E/System(4180): at java.lang.Daemons$FinalizerDaemon.run(Daemons.java:168) 12-31 22:05:51.324: E/System(4180): at java.lang.Thread.run(Thread.java:856) 

Lo extraño es que he usado código similar preciously y funcionó perfectamente. Además, otros métodos de la misma clase de base de datos funciona perfectamente.

Código de la actividad que llama a updateProject:

 public class UpdateProject extends Activity implements OnItemSelectedListener, DatePickerDialog.OnDateSetListener { int mPos; String mSelection; String pname; String pdifficulty; int pday; int pmonth; int pyear; String id; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_update_project); id = getIntent().getExtras().getString("idforupdate"); userdatabase viewname = new userdatabase(this); //Get username viewname.open(); String name = viewname.getusername(); viewname.close(); if(name.equals("")) { DialogFragment newFragment = new NouserexitFragment(); newFragment.show(getFragmentManager(), "exit"); } Spinner spinner = (Spinner) findViewById(R.id.difficultyspinner); ArrayAdapter<CharSequence> adapter = ArrayAdapter.createFromResource(this,R.array.difficultyarray, android.R.layout.simple_spinner_item); adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); spinner.setAdapter(adapter); spinner.setOnItemSelectedListener(this); pdifficulty = spinner.getSelectedItem().toString(); } @Override public boolean onCreateOptionsMenu(Menu menu) { // Inflate the menu; this adds items to the action bar if it is present. getMenuInflater().inflate(R.menu.activity_update_project, menu); return true; } @TargetApi(Build.VERSION_CODES.HONEYCOMB) public void datepicker(View v) { //Date picker DialogFragment newFragment = new DatePickerForUpdate(); newFragment.show(getFragmentManager(), "datePickerforupdate"); } @Override public void onDateSet(DatePicker view, int year, int month, int day) { // TODO Auto-generated method stub pday = day; pmonth = month +1; pyear = year; month = month + 1; Button activityButton = (Button)findViewById(R.id.datebutton); activityButton.setText (day + "." + month + "." + year); } @Override public void onItemSelected(AdapterView<?> parent, View view, int pos, long id) { // TODO Auto-generated method stub UpdateProject.this.mPos = pos; UpdateProject.this.mSelection = parent.getItemAtPosition(pos).toString(); } @Override public void onNothingSelected(AdapterView<?> arg0) { // TODO Auto-generated method stub } public void update_project(View view) { EditText cinone = (EditText) findViewById(R.id.pname); pname = cinone.getText().toString(); String fdate = pday + ". " + pmonth + ". " + pyear; projectdatabase update = new projectdatabase(UpdateProject.this); update.open(); update.updateProject(id, pname, fdate); update.close(); } 

}

Código para la clase de base de datos:

 public class projectdatabase { public static final String KEY_ROWID = "_id"; public static final String PROJECT_NAME = "project_name"; public static final String PROJECT_ID = "project_id"; public static final String PROJECT_DIFFICULTY = "project_difficulty"; public static final String PROJECT_STATUS = "project_status"; public static final String PROJECT_START_DATE = "project_start_date"; public static final String PROJECT_FINISH_DATE = "project_finsish_date"; private static final String DATABASE_NAME = "project_db"; static final String DATABASE_TABLE = "project_details"; private static final int DATABASE_VERSION = 1; private DbHelper ourHelper; private final Context projectdbContext; private SQLiteDatabase projectDatabase; private static class DbHelper extends SQLiteOpenHelper { public DbHelper(Context context) { super(context, DATABASE_NAME, null, DATABASE_VERSION); } @Override public void onCreate(SQLiteDatabase db) { // TODO Auto-generated method stub db.execSQL("CREATE TABLE "+ DATABASE_TABLE + " (" + KEY_ROWID + " INTEGER PRIMARY KEY AUTOINCREMENT, " + PROJECT_NAME + " TEXT NOT NULL, " + PROJECT_ID + " INTEGER, " + PROJECT_START_DATE + " TEXT, " + PROJECT_FINISH_DATE + " TEXT, " + PROJECT_DIFFICULTY + " TEXT, " + PROJECT_STATUS + " TEXT);" ); } @Override public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { // TODO Auto-generated method stub db.execSQL("DROP TABLE IF EXIST " + DATABASE_NAME); onCreate(db); } } public projectdatabase (Context c) { projectdbContext = c; } public projectdatabase open() { //Open database ourHelper = new DbHelper(projectdbContext); projectDatabase = ourHelper.getWritableDatabase(); return this; } public void close() { //Close database ourHelper.close(); } public long createEntry(String name, String pid, String startdate, String finishdate, String difficulty, String Status) { //Enter project data into database ContentValues cv = new ContentValues(); cv.put(PROJECT_NAME, name); cv.put(PROJECT_ID, pid); cv.put(PROJECT_START_DATE, startdate); cv.put(PROJECT_FINISH_DATE, finishdate); cv.put(PROJECT_DIFFICULTY, difficulty); cv.put(PROJECT_STATUS, Status); return projectDatabase.insert(DATABASE_TABLE, null, cv); } public String getData() { //Retrieve all project data String[] columns = new String[] {KEY_ROWID, PROJECT_NAME, PROJECT_ID, PROJECT_START_DATE, PROJECT_FINISH_DATE, PROJECT_DIFFICULTY, PROJECT_STATUS}; Cursor c = projectDatabase.query(DATABASE_TABLE, columns, null, null, null, null, null); String result = ""; int iRow = c.getColumnIndex(KEY_ROWID); int iName = c.getColumnIndex(PROJECT_NAME); int iID = c.getColumnIndex(PROJECT_ID); int iStartDate = c.getColumnIndex(PROJECT_START_DATE); int iFinishDate = c.getColumnIndex(PROJECT_FINISH_DATE); int iDifficulty = c.getColumnIndex(PROJECT_DIFFICULTY); int iStatus = c.getColumnIndex(PROJECT_STATUS); for(c.moveToFirst(); !c.isAfterLast(); c.moveToNext()) { result = result + c.getString(iRow) + "|" + c.getString(iName) + "|" + c.getString(iID) + "|" + c.getString(iStartDate) + "|" + c.getString(iFinishDate) + "|" + c.getString(iDifficulty) + "|" + c.getString(iStatus) + "\n"; } return result; } public Cursor getDataforDisplay () { //Project data for list view String[] columns = new String[] {KEY_ROWID, PROJECT_NAME, PROJECT_FINISH_DATE, PROJECT_DIFFICULTY, PROJECT_STATUS}; Cursor c = projectDatabase.query(DATABASE_TABLE, columns, null, null, null, null, null); c.moveToFirst(); return c; } public String getProjectName(String id) { String[] columns = new String[] {PROJECT_NAME,KEY_ROWID}; Cursor c = projectDatabase.query(DATABASE_TABLE, columns, KEY_ROWID + "=" + id, null, null, null, null); if(c != null) { int iName = c.getColumnIndex(PROJECT_NAME); c.moveToFirst(); String name = c.getString(iName); return name; } return null; } 

public String getProjectStatus (String id) {

  String[] columns = new String[] {PROJECT_STATUS,KEY_ROWID}; Cursor c = projectDatabase.query(DATABASE_TABLE, columns, KEY_ROWID + "=" + id, null, null, null, null); if(c != null) { int iStatus = c.getColumnIndex(PROJECT_STATUS); c.moveToFirst(); String status = c.getString(iStatus); return status; } return null; } 

public String getProjectDifficulty (String id) {

 String[] columns = new String[] {PROJECT_DIFFICULTY,KEY_ROWID}; Cursor c = projectDatabase.query(DATABASE_TABLE, columns, KEY_ROWID + "=" + id, null, null, null, null); if(c != null) { int iDiff = c.getColumnIndex(PROJECT_DIFFICULTY); c.moveToFirst(); String diff = c.getString(iDiff); return diff; } return null; 

}

public String getProjectstartdate (String id) {

 String[] columns = new String[] {PROJECT_START_DATE,KEY_ROWID}; Cursor c = projectDatabase.query(DATABASE_TABLE, columns, KEY_ROWID + "=" + id, null, null, null, null); if(c != null) { int iSdate = c.getColumnIndex(PROJECT_START_DATE); c.moveToFirst(); String sdate = c.getString(iSdate); return sdate; } return null; 

}

public String getProjectfinishdate (String id) {

 String[] columns = new String[] {PROJECT_FINISH_DATE,KEY_ROWID}; Cursor c = projectDatabase.query(DATABASE_TABLE, columns, KEY_ROWID + "=" + id, null, null, null, null); if(c != null) { int iFdate = c.getColumnIndex(PROJECT_FINISH_DATE); c.moveToFirst(); String fdate = c.getString(iFdate); return fdate; } return null; 

}

public void updateProject (String id, String PName, String FDate) {// método para actualizar la base de datos

 ContentValues cvUpdate = new ContentValues(); cvUpdate.put(PROJECT_NAME, PName); cvUpdate.put(PROJECT_FINISH_DATE, FDate); projectDatabase.update(DATABASE_TABLE, cvUpdate, KEY_ROWID + "=" + id, null); 

}

}

EDIT: Si reemplazo updateProject () método con cualquier otro método de la clase de base de datos, el error desaparece y la aplicación se ejecuta sin ningún problema.

Necesitas diseñar correctamente tu clase SQLiteOpenHelper . Muchos gurús sugieren hacer una referencia estática que garantice que sólo existe una instancia de DatabaseHelper en cualquier momento.

Debajo del código le dará una idea acerca de ello. (Esto no es un código completo, pero le dará una pista)

 public class DatabaseHelper extends SQLiteOpenHelper { private static DatabaseHelper mDBHelper; public static DatabaseHelper getInstance(Context ctx) { if (mDBHelper == null) { //this will ensure no multiple instances out there. mDBHelper = new DatabaseHelper(ctx.getApplicationContext()); } return mDBHelper; } } 

Ahora, haz un truco.

abra la base de datos

 private SQLiteDatabase db; public synchronized SQLiteDatabase open() throws SQLException { if(db ==null){ db = DBHelper.getWritableDatabase(); } return db; } 

Cierre la base de datos.

 public synchronized void close() { //do nothing. This is a trick. } 

Razón: Para aplicaciones móviles, no hay necesidad de mecanismo de apertura y cierre. Es el más adecuado para la aplicación web donde varios usuarios están tratando de acceder a db, pero en el caso de la aplicación móvil, sólo un usuario va a utilizar su aplicación.

Este hack también se asegurará de que nunca obtendrá el Close() was never explicitly called on database error de Close() was never explicitly called on database . Esta excepción se activa cuando se han abierto más instancias de SQLiteDatabase que las que se han cerrado y ahora en nuestro caso sólo hay una instancia de SQLiteDatabse. Esto también controlará el problema de acceso / escritura de acceso concurrente.

Espero que este hack le ayudará a entender el problema real.

Para una mejor comprensión, puede consultar este enlace .

 public projectdatabase open() { ourHelper = new DbHelper(projectdbContext); projectDatabase = ourHelper.getWritableDatabase(); return this; } public void close() { ourHelper.close(); } 

Allí arriba, trate de cambiar ourHelper.close() a projectDatabase.close() . Debe cerrar la instancia de la base de WriteableDatabase WriteableDatabase de WriteableDatabase que abrió. No es el DBHelper .

Así que su función cercana se convertiría en:

 public void close() { projectDatabase.close(); } 

[EDIT] : Desde el sitio web sqlite encontré esta información . La razón por la que funciona cuando se reemplaza updateProject() con cualquier otro método es porque es el único método en el que se obtiene un bloqueo de escritura en la base de datos. Las bases de datos SQLite no tienen bloqueo de lectura, sólo un bloqueo de escritura.

¿Has intentado cerrar una llamada en la base de datos de proyecto al final de tu método updateProject() )?

Otra sugerencia que haría es hacer que su clase de base de datos sea singleton . Esto evitaría cualquier conflicto ya que habría un solo objeto que accediera al db en un momento dado.

  • Eliminar todos los datos de todas las tablas de Sugar ORM
  • Android: actualización de la base de datos de usuarios con SQLiteAssetHelper
  • Inserción o actualización de SQLite de Android
  • Cómo capturar excepción en la transacción sqllite - java android
  • insertar si no existe otra actualización en sqlite android
  • ¿Cómo debo notificar al usuario que SQLite Asset Helper está cargando la base de datos por primera vez?
  • Columnas únicas en Sugar ORM
  • Causado por: android.database.sqlite.SQLiteException: No se puede actualizar la base de datos de sólo lectura de la versión 0 a 1
  • Android - Base de datos pre-poblada, insertada o pre-cargada?
  • Creo que he llegado con la peor manera de comparar dos fechas; ¿es posible hacerlo mejor?
  • Android SQLite nueva versión de DB con una tabla eliminada
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.