2011-02-09 11 views
9

Aquí está el error:Obtengo una excepción de objeto de base de datos no cerrada en SQLite (Android), pero estoy cerrando explícitamente mi base de datos ... ¿Ayuda?

02-08 16: 35: 00,899: ERROR/base de datos (468): android.database.sqlite.DatabaseObjectNotClosedException: Aplicación no cerró el objeto cursor o base de datos que se abrió aquí

Excepto, bueno, yo soy. Aquí es donde el método de este problema se está produciendo:

public static void getUpdates(String username, Context context) { 
    HttpClient httpClient = new DefaultHttpClient(); 
    HttpPost httpPost = new HttpPost("http://10.0.2.2/tag/appgetfriendinfo.php"); 

    try { 
     List<NameValuePair> nVPs = new ArrayList<NameValuePair>(); 
     nVPs.add(new BasicNameValuePair("username", username)); 

     httpPost.setEntity(new UrlEncodedFormEntity(nVPs)); 
     HttpResponse response = httpClient.execute(httpPost); 

     ResponseHandler<String> rHandler = new BasicResponseHandler(); 
     String result = rHandler.handleResponse(response); 

     JSONArray jArray = new JSONArray(result); 
     for(int i = 0; i < jArray.length(); i++) { 
      JSONObject jObj = jArray.getJSONObject(i); 
      String userCheck = jObj.getString("username"); 
      TagDBAdapter dbHelper = new TagDBAdapter(context); 
      dbHelper.open();//OPENING THE DATABASE 
      Contact contact = new Contact(); 

      String first = jObj.getString("firstname"); 
      String last = jObj.getString("lastname"); 
      String name = first + " " + last; 

      contact.setUsername(jObj.getString("username")); 
      contact.setFirstName(first); 
      contact.setLastName(last); 
      contact.setName(name); 
      contact.setPhoneNumber(jObj.getString("phonenumber")); 
      contact.setEmail(jObj.getString("email")); 
      contact.setHomePhone(jObj.getString("homephone")); 
      contact.setWorkPhone(jObj.getString("workphone")); 

      if(dbHelper.checkForExisting(userCheck) == true) { 
       dbHelper.createContact(contact); 
      } 
      else { 
       dbHelper.updateContactAuto(userCheck, contact); 
      } 
      dbHelper.close();//CLOSING THE DATABASE 
     } 

    } catch(ClientProtocolException e) { 
     Log.e("GETUPDATES", "CPE", e); 
     e.printStackTrace(); 
    } catch(IOException e) { 
     Log.e("GETUPDATES", "IOE", e); 
     e.printStackTrace(); 
    } catch(JSONException e) { 
     Log.e("GETUPDATES", "JSONE", e); 
     e.printStackTrace(); 
    } 
} 

Como se puede ver en las líneas que se señala en los comentarios //, estoy apertura y cierre de la base de datos, sin embargo, todavía estoy recibiendo el error. Aquí está lo extraño, el origen del error está en el método open() de SQLite.

ERROR/Base de datos (468): a com.tagapp.android.TagDBAdapter.open (TagDBAdapter.java:62)

¿Cuál es la siguiente:

/**THESE ARE MY DBADAPTER'S OPEN AND CLOSE METHODS*/ 

    public TagDBAdapter open() throws SQLException { 
    mDBHelper = new DatabaseHelper(m_context); 
    mDb = mDBHelper.getWritableDatabase(); 
    return this; 
} 

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

Estos son directamente de Google de tutorial de bloc de notas, y han funcionado 100% para mí en diferentes instancias. ¿Alguien tiene una idea de lo que está pasando aquí? Muchas gracias.

+0

@psyhclo que había necesito ver su actividad para ayudarlo allí, si puede publicarlo, intentaré y ayudaré – JMRboosties

+0

ok, agregué la actividad al final de la publicación. puedes consultar el mismo enlace http://www.stackoverflow.com/questions/4921550/where-to-close-the-database Gracias. – rogcg

+0

Eso es raro ... parece que debería cerrarse. Asegúrese de que sus métodos DBAdapter cierren los cursores, supongo, pero de su actividad se ve bien. Lo siento, no podría ser de más ayuda. – JMRboosties

Respuesta

12

El problema no es el objeto de la base de datos, es el cursor; tiene un cursor abierto por ahí.

Asegúrese de que todos los cursores estén cerrados antes de cerrar la base de datos. (Por cierto, si quieres ser elegante, puedes crear un ContentProvider, usar SQLiteOpenHelper y no preocuparte por cerrarlo).

+0

Utilizo un cursor en el método checkForExisting (...), es probable que, gracias. Si eso no ayuda, lo publicaré como referencia para futuros respondedores. Gracias. – JMRboosties

+2

También puede usar 'startManagingCursor (Cursor)' para permitir que Android administre el cursor por usted. Este es el más útil si está vinculando los datos a un 'ListView'. –

+1

Sí, eso resolvió el problema, pero por supuesto ahora tengo uno completamente nuevo. ¡Muchas gracias! – JMRboosties

0

Al analizar esto, estoy investigando un problema similar. Una posibilidad que noto es que si lanzas una excepción en tu bucle por cualquier razón, incluso si lo manejas adecuadamente, sales del bucle y el último open() nunca tiene un cierre correspondiente. Para arreglar esto, querrá poner la sentencia close() en un bloque finally {}. Además, no veo ninguna razón para crear y abrir un nuevo cursor para cada iteración del ciclo. Mueva eso fuera del bucle para que haya uno y solo uno abierto() y el cierre correspondiente() es el que está en el bloque finally. (alternativamente, puede tener otro try-catch construir dentro del bucle, por lo que el cierre() siempre se ejecute.)

Ejemplo:

public static void getUpdates(String username, Context context) { 
HttpClient httpClient = new DefaultHttpClient(); 
HttpPost httpPost = new HttpPost("http://10.0.2.2/tag/appgetfriendinfo.php"); 
TagDBAdapter dbHelper; // DECLARE THIS HERE SO IT CAN BE ACCESSED OUTSIDE OF try BLOCK 
try { 
    List<NameValuePair> nVPs = new ArrayList<NameValuePair>(); 
    nVPs.add(new BasicNameValuePair("username", username)); 

    httpPost.setEntity(new UrlEncodedFormEntity(nVPs)); 
    HttpResponse response = httpClient.execute(httpPost); 

    ResponseHandler<String> rHandler = new BasicResponseHandler(); 
    String result = rHandler.handleResponse(response); 

    JSONArray jArray = new JSONArray(result); 

    // MOVED TO OUTSIDE OF LOOP 
    dbHelper = new TagDBAdapter(context); 
    dbHelper.open();//OPENING THE DATABASE 
    for(int i = 0; i < jArray.length(); i++) { 
     JSONObject jObj = jArray.getJSONObject(i); 
     String userCheck = jObj.getString("username"); 
     Contact contact = new Contact(); 

     String first = jObj.getString("firstname"); 
     String last = jObj.getString("lastname"); 
     String name = first + " " + last; 

     contact.setUsername(jObj.getString("username")); 
     contact.setFirstName(first); 
     contact.setLastName(last); 
     contact.setName(name); 
     contact.setPhoneNumber(jObj.getString("phonenumber")); 
     contact.setEmail(jObj.getString("email")); 
     contact.setHomePhone(jObj.getString("homephone")); 
     contact.setWorkPhone(jObj.getString("workphone")); 

     if(dbHelper.checkForExisting(userCheck) == true) { 
      dbHelper.createContact(contact); 
     } 
     else { 
      dbHelper.updateContactAuto(userCheck, contact); 
     } 
    } 

} catch(ClientProtocolException e) { 
    Log.e("GETUPDATES", "CPE", e); 
    e.printStackTrace(); 
} catch(IOException e) { 
    Log.e("GETUPDATES", "IOE", e); 
    e.printStackTrace(); 
} catch(JSONException e) { 
    Log.e("GETUPDATES", "JSONE", e); 
    e.printStackTrace(); 
} finally { 
    dbHelper.close();//CLOSING THE DATABASE 
} 

}

Cuestiones relacionadas