2012-10-09 30 views
19

i sql işleyicisi ile olan sorunAndroid SQLite sızan

A SQLiteConnection object for database '/data/data/.../databases/queueManager' was leaked! Please fix your application to end transactions in progress properly and to close the database when it is no longer needed. 

Androidhive öğretici alınan ve benim kullanımı için özelleştirilmiş

tablo görünüyor

+ ----------------------------------------------------------- + 
: DATABASE_ID : DATABASE_QID : DATABASE_QUEUE : DATABASE_DATE : 
+ ----------------------------------------------------------- + 

kod gibi

DBQueue searchDBqid(int id) { 
     SQLiteDatabase db = this.getReadableDatabase(); 

     String selectQuery = "SELECT * FROM " + TABLE_QUEUE + " WHERE " + DATABASE_QID + " = " + id; 

      Cursor cursornum = db.rawQuery(selectQuery, null); 
      int dk = cursornum.getCount(); 
      cursornum.close(); 

      if (dk >0) { 
       Cursor cursor = db.query(TABLE_QUEUE, new String[] { DATABASE_ID, 
         DATABASE_QID, DATABASE_QUEUE, DATABASE_DATE }, DATABASE_QID + "=?", 
         new String[] { String.valueOf(id) }, null, null, null, null); 

       if (cursor != null) cursor.moveToFirst(); 

       DBQueue dbqueue = new DBQueue(Integer.parseInt(cursor.getString(0)), 
         cursor.getString(1), cursor.getString(2), cursor.getString(3)); 
       return dbqueue; 
      } 

     db.close(); 
     return null; 
    } 

    DBQueue getDBQueue(int id) { 
     SQLiteDatabase db = this.getReadableDatabase(); 

     Cursor cursor = db.query(TABLE_QUEUE, new String[] { DATABASE_ID, 
       DATABASE_QID, DATABASE_QUEUE }, DATABASE_ID + "=?", 
       new String[] { String.valueOf(id) }, null, null, null, null); 
     if (cursor != null) 
      cursor.moveToFirst(); 

     DBQueue dbqueue = new DBQueue(Integer.parseInt(cursor.getString(0)), 
       cursor.getString(1), cursor.getString(2), cursor.getString(3)); 
     return dbqueue; 
    } 


    public String getAllqid() { 
     Time today = new Time(Time.getCurrentTimezone()); 
     today.setToNow(); 

     String selectQuery = "SELECT * FROM " + TABLE_QUEUE + " WHERE " + DATABASE_DATE + " = '" + today.format("%d %m %Y") + "'"; 

     SQLiteDatabase db = this.getWritableDatabase(); 
     Cursor cursor = db.rawQuery(selectQuery, null); 

     StringBuilder sb = new StringBuilder();  
     if (cursor.moveToFirst()) { 
      do { 
       if (sb.length() > 0) sb.append(','); 
       sb.append(cursor.getString(1)); 
      } while (cursor.moveToNext()); 
     } 

     String result = sb.toString(); 
     return result; 
    } 
    public void deleteDatedDBQueue() { 
     Time today = new Time(Time.getCurrentTimezone()); 
     today.setToNow(); 
     String selectQuery = "SELECT * FROM " + TABLE_QUEUE + " WHERE " + DATABASE_DATE + " != '" + today.format("%d %m %Y") + "'"; ; 

     SQLiteDatabase db = this.getWritableDatabase(); 
     Cursor cursor = db.rawQuery(selectQuery, null); 

     if (cursor.moveToFirst()) { 
      do { 
       db.delete(TABLE_QUEUE, DATABASE_ID + " = ?", 
         new String[] { String.valueOf(Integer.parseInt(cursor.getString(0))) }); 
      } while (cursor.moveToNext()); 
     } 
     db.close(); 
    } 
    public int getDBQueueCount() { 
     String countQuery = "SELECT * FROM " + TABLE_QUEUE; 
     SQLiteDatabase db = this.getReadableDatabase(); 
     Cursor cursor = db.rawQuery(countQuery, null); 
     cursor.close(); 

     return cursor.getCount(); 
    } 
} 

Birisi olabilir lütfen bana bu sızıntının nasıl düzeltileceğini söyle?

tam kodu: http://ijailbreak.me/databasehandler.txt

cevap

50

SQLiteDatabase kapatıp kaçınmak gerekmez. Bunu yapmanın geleneksel yoludur:

Cursor cursor = db.query(...); 
try { 
    // read data from the cursor in here 
} finally { 
    cursor.close(); 
} 

Ama şimdi, try-with-resources ile, çok daha özlü olabilir:

try (Cursor cursor = db.query(...)) { 
    // read data from the cursor in here 
} 
+0

Ayrıca, açık yardımcısı kapsam dışına çıktığı zaman, veritabanının kapalı kalacağı yöntemlerden bazılarının kapalı olmadığından da bunu düşünüyorum çünkü cevabımda açık yardımcının açık kalmasını önlemek için tek bir yardımcısını Birden çok iş parçacığı arasında kullanmayı denediğinde yalnızca daha da kötüleşecek sorunları kapatın :) –

+6

Evet, veritabanı bağlantısı her zaman bir tekil olmalıdır. –

+0

Tamam, İmleç'i her kullandığımda bu yöntemi kullandım. ve birkaç db.close() ekledi; ve bence sorunu çözüyor. Teşekkürler ! – Kirma

8

Sen, çeşitli vesilelerle sizin imleçlerini kapatmayı unutmak için yapıldığında her zaman imleç kapatmak emin olun.

Örneğin, ikinci sorgu imleç kapatmaz, ben size tasarımını değiştirirseniz, getDBQueue, getAllqid ve getDBQueueCount yapılan Bir zamanların SQLiteDatabase kapatmayın netlik Ayrıca

için TODO'd var senin SQLiteOpenHelper a tek yapmak o zaman sızıntısı onunla bittiğinde Her Cursor kapatılmalıdır

DBQueue searchDBqid(int id) { 
     SQLiteDatabase db = this.getReadableDatabase(); 

     String selectQuery = "SELECT * FROM " + TABLE_QUEUE + " WHERE " + DATABASE_QID + " = " + id; 

      Cursor cursornum = db.rawQuery(selectQuery, null); 
      int dk = cursornum.getCount(); 
      cursornum.close(); 

      if (dk >0) { 

       // TODO: Close this cursor! 
       Cursor cursor = db.query(TABLE_QUEUE, new String[] { DATABASE_ID, 
         DATABASE_QID, DATABASE_QUEUE, DATABASE_DATE }, DATABASE_QID + "=?", 
         new String[] { String.valueOf(id) }, null, null, null, null); 

       if (cursor != null) cursor.moveToFirst(); 

       DBQueue dbqueue = new DBQueue(Integer.parseInt(cursor.getString(0)), 
         cursor.getString(1), cursor.getString(2), cursor.getString(3)); 
       return dbqueue; 
      } 

     db.close(); 
     return null; 
    } 
0

ilk kez açık veritabanı ve son arz bu kodu.

@Override 
     protected void onDestroy() { 
      // TODO Auto-generated method stub 
     mdb.close(); 
     super.onDestroy(); 
     } 
1

Bir veritabanını her açtığınızda (okunabilir veya yazılabilir) ve kullanarak ayırmanın için gelmiştir bellek kaynaklarını kullanır imleç ".close();" kullanım örneğin her veritabanı işlevinde sona erdikten sonra: vb

if (cursor != null) cursor.moveToFirst(); 

       DBQueue dbqueue = new DBQueue(Integer.parseInt(cursor.getString(0)), 
         cursor.getString(1), cursor.getString(2), cursor.getString(3)); 
       return dbqueue; 
      } 
cursor.close(); 

     db.close(); 
     return null; 
    } 

DBQueue getDBQueue(int id) { 
     SQLiteDatabase db = this.getReadableDatabase(); 

     Cursor cursor = db.query(TABLE_QUEUE, new String[] { DATABASE_ID, 
       DATABASE_QID, DATABASE_QUEUE }, DATABASE_ID + "=?", 
       new String[] { String.valueOf(id) }, null, null, null, null); 
     if (cursor != null) 
      cursor.moveToFirst(); 

     DBQueue dbqueue = new DBQueue(Integer.parseInt(cursor.getString(0)), 
       cursor.getString(1), cursor.getString(2), cursor.getString(3)); 
cursor.close(); 
db.close(); 
     return dbqueue; 
    } 

ve .... !!