2014-12-31 71 views
0

我正在通過有關此問題的stackoverflow閱讀,但我仍未找到解決方案。有時我的應用程序面臨這個問題這是我的錯誤日誌,Android- java.lang.IllegalStateException:無法執行此操作,因爲連接池已關閉

12-31 10:58:28.025: E/AndroidRuntime(16322): FATAL EXCEPTION: Timer-0 
12-31 10:58:28.025: E/AndroidRuntime(16322): java.lang.IllegalStateException: Cannot perform this operation because the connection pool has been closed. 
12-31 10:58:28.025: E/AndroidRuntime(16322): at android.database.sqlite.SQLiteConnectionPool.throwIfClosedLocked(SQLiteConnectionPool.java:1031) 
12-31 10:58:28.025: E/AndroidRuntime(16322): at android.database.sqlite.SQLiteConnectionPool.waitForConnection(SQLiteConnectionPool.java:746) 
12-31 10:58:28.025: E/AndroidRuntime(16322): at android.database.sqlite.SQLiteConnectionPool.acquireConnection(SQLiteConnectionPool.java:400) 
12-31 10:58:28.025: E/AndroidRuntime(16322): at android.database.sqlite.SQLiteSession.acquireConnection(SQLiteSession.java:905) 
12-31 10:58:28.025: E/AndroidRuntime(16322): at android.database.sqlite.SQLiteSession.executeForCursorWindow(SQLiteSession.java:834) 
12-31 10:58:28.025: E/AndroidRuntime(16322): at android.database.sqlite.SQLiteQuery.fillWindow(SQLiteQuery.java:62) 
12-31 10:58:28.025: E/AndroidRuntime(16322): at android.database.sqlite.SQLiteCursor.fillWindow(SQLiteCursor.java:144) 
12-31 10:58:28.025: E/AndroidRuntime(16322): at android.database.sqlite.SQLiteCursor.getCount(SQLiteCursor.java:133) 
12-31 10:58:28.025: E/AndroidRuntime(16322): at android.database.AbstractCursor.moveToPosition(AbstractCursor.java:197) 
12-31 10:58:28.025: E/AndroidRuntime(16322): at android.database.AbstractCursor.moveToFirst(AbstractCursor.java:237) 
12-31 10:58:28.025: E/AndroidRuntime(16322): at com.eyepax.horseapp.data.dbadapters.ContactGroupDbAdapter.getContactGroups(ContactGroupDbAdapter.java:138) 
12-31 10:58:28.025: E/AndroidRuntime(16322): at com.eyepax.horseapp.data.DataManager.getGroups(DataManager.java:1548) 
12-31 10:58:28.025: E/AndroidRuntime(16322): at com.eyepax.horseapp.sync.ContactSync.contactGroupSync(ContactSync.java:43) 
12-31 10:58:28.025: E/AndroidRuntime(16322): at com.eyepax.horseapp.service.SynchingService.callSync(SynchingService.java:77) 
12-31 10:58:28.025: E/AndroidRuntime(16322): at com.eyepax.horseapp.service.SynchingService.access$0(SynchingService.java:70) 
12-31 10:58:28.025: E/AndroidRuntime(16322): at com.eyepax.horseapp.service.SynchingService$1.run(SynchingService.java:57) 

這是墜毀在ContacGroupDbAdapter類中的方法,

/** 
* Returns ContactGroup. 
* 
* @return ArrayList<ContactGroup> 
*/ 
public ArrayList<ContactGroup> getContactGroups() { 

    this.open(); 
    Cursor cursor = database.rawQuery("SELECT * FROM " + TABLE_NAME, null); 
    ArrayList<ContactGroup> list = null; 

    if (cursor != null && cursor.moveToFirst()) { 
     list = new ArrayList<ContactGroup>(); 

     do { 
      try { 
       ContactGroup contactGroup = new ContactGroup(); 
       contactGroup.setGroupId(cursor.getString(cursor.getColumnIndex(GROUP_ID))); 
       contactGroup.setGroupName(cursor.getString(cursor.getColumnIndex(GROUP_NAME))); 
       contactGroup.setIsDeleted(cursor.getInt(cursor.getColumnIndex(GROUP_IS_DELETED))); 
       contactGroup.setUpdatedDate(cursor.getString(cursor.getColumnIndex(GROUP_UPDATE_DATE))); 
       contactGroup.setIsSync(cursor.getInt(cursor.getColumnIndex(GROUP_IS_SYNC))); 

       list.add(contactGroup); 
      } catch (Exception e) { 

      } 
     } while (cursor.moveToNext()); 

    } 

    if (cursor != null) 
     cursor.close(); 
    return list; 
} 

而且它在該行cursor.moveToFirst()與此錯誤崩潰。請幫我解決這個問題。

我用單獨BaseDbAdapter類關閉分貝,

public class BaseDbAdapter { 

/** 
* Application context. 
*/ 
protected Context context; 

/** 
* Database. 
*/ 
protected SQLiteDatabase database; 

/** 
* Database helper class. 
*/ 
protected SQLiteDataBaseHelper dbHelper; 

/** 
* StringBuilder 
*/ 
protected StringBuilder stringBuilder; 

public static final String CREATE_TABLE_PRE_TEXT = "create table if not exists "; 
/** 
* Returns StringBuilder object. 
* 
* @return 
*/ 
protected StringBuilder getStringBuilder() { 
    if (stringBuilder == null) { 
     stringBuilder = new StringBuilder(); 
    } 

    return stringBuilder; 
} 

/** 
* Opens a connection to the database. 
* 
* @throws SQLException 
*/ 
public synchronized void open() throws SQLException { 
    dbHelper = SQLiteDataBaseHelper.getInstance(context); 
    database = dbHelper.getWritableDatabase(); 
} 

/** 
* Closes the connection. 
*/ 
public synchronized void close() { 
    database.close(); 
} 

public static String getDeleteTableStatement(String tableName) { 
    return "DELETE TABLE " + tableName; 
} 

}

我用SQLiteDataBaseHelper類和作爲同步其getInstance方法改變。
as this answer但仍然問題沒有解決。

/** 
* Get an instance of SQLiteDataBaseHelper. 
* 
* @param context 
* @return SQLiteDataBaseHelper 
*/ 
public static synchronized SQLiteDataBaseHelper getInstance(Context context) { 

    // if(dbName == null) { 
    // dbName = DataManager.getSQLiteDatabaseName(context); 
    // } 

    if (instance == null) { 
     instance = new SQLiteDataBaseHelper(context); 

    } 

    return instance; 
} 
+0

你在哪裏關閉你的數據庫? –

+0

我用單獨的BaseDbAdapter類來關閉數據庫檢查我編輯的問題 – user3800832

+0

移動getContactGroups移動到BaseDbAdapter – koutuk

回答

0
public ArrayList<ContactGroup> getContactGroups() { 
     ArrayList<ContactGroup> list = null; 
     try { 
       // TODO Auto-generated method stub 
       SQLiteDatabase database = this.getWritableDatabase(); 
     Cursor cursor = database.rawQuery("SELECT * FROM " + TABLE_NAME, null); 
     if (cursor != null && cursor.moveToFirst()) { 
      list = new ArrayList<ContactGroup>(); 


       try { 
        while (cursor.moveToNext()) 
        { 
        ContactGroup contactGroup = new ContactGroup(); 
        contactGroup.setGroupId(cursor.getString(cursor.getColumnIndex(GROUP_ID))); 
        contactGroup.setGroupName(cursor.getString(cursor.getColumnIndex(GROUP_NAME))); 
        contactGroup.setIsDeleted(cursor.getInt(cursor.getColumnIndex(GROUP_IS_DELETED))); 
        contactGroup.setUpdatedDate(cursor.getString(cursor.getColumnIndex(GROUP_UPDATE_DATE))); 
        contactGroup.setIsSync(cursor.getInt(cursor.getColumnIndex(GROUP_IS_SYNC))); 

        list.add(contactGroup); 
         } 
       } catch (Exception e) { 

       } 


     } 

     if (cursor != null) 
    { 
      cursor.close(); 
     database.close(); 
    } 
    } catch (Exception e) { 

       } 

     return list; 
    } 

try this effort 
+0

這是行不通的 – user3800832

+0

你在哪裏放這個代碼 – koutuk

+0

我把這些代碼ContactGroupDbAdapter類,它擴展了BaseDbAdapter類。 – user3800832

1

我認爲這個問題是synchronization。當多個線程同時訪問有關於你的數據庫的狀態誤解。

你應該避免讓數據庫成爲一個實例變量,而是在輔助類(最好是擴展SQLiteOpenHelper)中使它成爲本地方法。獲取數據庫並在其上工作的一個例子如下所示:

public void addContact(Contact contact) { 
    SQLiteDatabase db = this.getWritableDatabase(); 

    ContentValues values = new ContentValues(); 
    values.put(KEY_NAME, contact.getName()); // Contact Name 
    values.put(KEY_PH_NO, contact.getPhoneNumber()); // Contact Phone Number 

    // Inserting Row 
    db.insert(TABLE_CONTACTS, null, values); 
    db.close(); // Closing database connection 
} 

請查看本教程:Android SQLite Database Tutorial

這裏是你可以怎麼做乾淨提議的例子:

public class DatabaseHelper extends SQLiteOpenHelper { 

    ...... 

    // no need to synchronize 
    public Cursor getBookList(){ 
     SQLiteDatabase db = getReadableDatabase(); // or getWritableDatabase() 
     Cursor c = db.query(BookEntry.TABLE_NAME, null, null, null, null, null, BookEntry.COLUMN_NAME + " ASC"); 
     return c; 
    } 

    // no need to override close method, because that one is very well coded already 
    // SQLiteOpenHelper will close any opened database, with its service close method. 
} 

public class SomeAdapter{ 


    // no need to synchronize, as all DatabaseHelper instances are method local 
    public int getBookCount(){ 
     DatabaseHelper dbHelper = new DatabaseHelper(context); 
     Cursor c = dbHelper.getBookList(); 
     int rowCount = c.getCount(); 
     c.close(); // close the cursor once used. 
     dbHelper.close(); // ask the helper to close any open database. 
     return rowCount; 

    } 

} 

請點擊這裏查看SQLiteOpenHelper.java:SQLiteOpenHelper.java 然後你就會知道如何數據庫(mDatabase)是由方法,如getReadableDatabase()保持,得到WritableDatabase()和close()。

+0

我使用SQLiteDataBaseHelper類及其getInstance方法更改爲synchronized。看到我編輯的問題。 – user3800832

+0

非靜態方法和靜態方法的同步將具有不同的鎖。打開和關閉方法將鎖定適配器對象。 SQLiteDataBaseHelper的getInstance方法將鎖定在SQLiteDataBaseHelper類對象上。 – ZakiMak

+0

我已經爲您添加了一個建議設計,並鏈接了SQLiteOpenHelper源代碼。 – ZakiMak

相關問題