2014-04-30 19 views
11

Android veritabanı ve imleçler ile ilgili garip bir sorunum var. Zaman zaman (çok nadiren), müşterilerden kaza raporu aldım. ~ 150.000 aktif kullanıcı ve belki de haftada 1 rapor var gibi, neden çökmek olduğunu anlamak zor, bu yüzden gerçekten küçük bir hata. İşte istisnadır:Android veritabanı - Bağlantı havuzu kapatıldığından bu işlem yapılamıyor

db = instance.getWritableDatabase(); 
cursor = db.rawQuery(selectQuery, null); 

if (isCursorEmptyOrNotPrepared(cursor)) { 
    ... 
    } 

private synchronized boolean isCursorEmptyOrNotPrepared(Cursor cursor) { 
     if (cursor == null) 
      return true; 

     if (cursor.isClosed()) 
      return true; 

     if (cursor.getCount() == 0) // HERE IT CRASHES 
      return true; 

     return false; 
    } 

Ve çizgisinde düşer:

STACK_TRACE=java.lang.IllegalStateException: Cannot perform this operation because the connection pool has been closed. 
at android.database.sqlite.SQLiteConnectionPool.throwIfClosedLocked(SQLiteConnectionPool.java:962) 
at android.database.sqlite.SQLiteConnectionPool.waitForConnection(SQLiteConnectionPool.java:599) 
at android.database.sqlite.SQLiteConnectionPool.acquireConnection(SQLiteConnectionPool.java:348) 
at android.database.sqlite.SQLiteSession.acquireConnection(SQLiteSession.java:894) 
at android.database.sqlite.SQLiteSession.executeForCursorWindow(SQLiteSession.java:834) 
at android.database.sqlite.SQLiteQuery.fillWindow(SQLiteQuery.java:62) 
at android.database.sqlite.SQLiteCursor.fillWindow(SQLiteCursor.java:144) 
at android.database.sqlite.SQLiteCursor.getCount(SQLiteCursor.java:133) 
at sk.mildev84.agendareminder.a.c.a(SourceFile:169) 

"yineleme ve keşfetmek" Ben her şeyi emin olmak için bu kodu her kullandığınızda imlecin önce tamam

if (cursor.getCount() == 0) 

Herkes nedenini biliyor mu? Tüm olası istisnaları ve koşulları kontrol ettiğimi düşünüyorum. Uygulamam neden burada çöküyor?

Not: Tüm veritabanı yöntemleri senkronize edilmiştir ve her durumda veritabanı/imleçleri doğru şekilde açıp kapatıyorum, birçok kez kontrol ettim. veritabanını kapattıktan sonra başka bir işlem çalışırsanız

+0

Daha fazla kod ve tam stacktrace gönderin. Bu iştahı alırsınız -> – nikis

+0

güncellenmiş bir yerde bir hata var. – qkx

+0

db'yi kapatmaya gerek yok. Android bunu hallediyor. Bu büyük açıklamayı buradan okuyun ...http://stackoverflow.com/questions/14002022/android-sq-lite-closed-exception/25379071#25379071 – Nepster

cevap

0

sadece Kaldır db.Close()

24

Sorun
kaldırmak, size o exception.Because db.close(); serbest bırakır nesneye bir başvuru, kapanış verecek Son referans serbest bırakılmışsa nesne.

Çözüm
statik bir şekilde tek SQLiteOpenHelper örneği (Singleton) tutun. Tembel başlatma ve synchronize bu yöntemi yapın. Böyle

public class DatabaseHelper 
{ 
    private static DatabaseHelper instance; 

    public static synchronized DatabaseHelper getInstance(Context context) 
    { 
     if (instance == null) 
      instance = new DatabaseHelper(context); 

     return instance; 
    } 
//Other stuff... 
} 

Ve olarak bunu kapatmak zorunda değil mi? Uygulama kapandığında, numaralı telefona bağlı olsa bile, dosya referansından ayrılır.
Örnek: Bir sonraki çağrıda tekrar kullanacağından DB'yi kapatmamalısınız. Yani sadece ben de bu sorun vardı Single SQLite connection

0

de görün Daha fazla bilgi için

db.close(); 

kaldırın. SQLiteOpenHelper sınıfım her CRUD işleminden sonra db'yi kapatmanın yanı sıra Singleton'du. benim SQLiteOpenHelper sınıfta senkronize Metotlarımı (CRUD) yaptıktan sonra ben hata alamadım bir daha :)

0

explanation okuduktan sonra ben
public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) den
db.close();
kaldırıldı böylece Aynı sorun, bana oluştu
ve
public int delete(Uri uri, String selection, String[] selectionArgs) ContentProvider'ın
yöntemi ContentProvider'ın kendisi gibi db.close() gereği veritabanının kapanmasına özen göstermez.

İlgili konular