我想在android中有一個連接池,因爲並行線程必須同時訪問數據庫。SQLite連接池
Android提供了PooledConnection
接口,用於與javax.sql連接一起使用。由於jdbc for SQLite在Android中沒有得到官方支持,我正在考慮另一種方法來實現SQLite數據庫的連接池。
您對這種方法有什麼看法。有什麼風險?我忽略了什麼?
我的代碼如下:
數據庫的連接包裝類:
public class PoolConnection {
protected SQLiteDatabase sqlDb;
protected long openedAt;
private static final String DB_NAME = Environment
.getExternalStorageDirectory()
+ "/data/DBNAME.sqlite";
private static final int DB_VERSION = 1;
private static class DatabaseHelper extends SQLiteOpenHelper {
DatabaseHelper(Context context) {
super(context, DB_NAME, null, DB_VERSION);
}
@Override
public void onCreate(SQLiteDatabase db) {
// nothing to do here
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
// no upgrade planned yet
}
}
public PoolConnection(Context context) throws Exception {
sqlDb = new DatabaseHelper(context).getWritableDatabase();
openedAt = System.currentTimeMillis();
}
public boolean isAvailable() {
if (!sqlDb.isOpen() || sqlDb.inTransaction()
|| sqlDb.isDbLockedByOtherThreads()) {
return false;
} else {
return true;
}
}
public void close() throws SQLException {
sqlDb.close();
}
public SQLiteDatabase getConnection() throws SQLException {
return sqlDb;
}
public long getOpenedAt() {
return openedAt;
}
}
和連接池類:
public class ConnectionPool {
protected List<PoolConnection> connections;
protected long maxIdleTime = 30 * 1000;
public ConnectionPool() {
connections = Collections
.synchronizedList(new ArrayList<PoolConnection>());
new PoolCleaner(maxIdleTime).start();
}
public PoolConnection getConnection(Context context) throws Exception {
synchronized (connections) {
PoolConnection poolCon = null;
for (PoolConnection con : connections) {
poolCon = con;
if (poolCon.isAvailable()) {
return poolCon;
}
}
}
PoolConnection con = new PoolConnection(context);
synchronized (connections) {
connections.add(con);
}
return con;
}
public void removeExpired() {
synchronized (connections) {
for (int i = (connections.size() - 1); i >= 0; i--) {
PoolConnection con = connections.get(i);
if (con.isAvailable()
&& maxIdleTime < (System.currentTimeMillis() - con
.getOpenedAt())) {
try {
con.close();
} catch (SQLException e) {
e.printStackTrace();
}
connections.remove(i);
}
}
}
}
class PoolCleaner extends Thread {
protected long cleaningInterval;
protected boolean mustStop;
public PoolCleaner(long cleaningInterval) {
if (cleaningInterval < 0) {
throw new IllegalArgumentException(
"cleaningInterval must be >= 0");
}
this.mustStop = false;
this.cleaningInterval = cleaningInterval;
setDaemon(true);
}
public void run() {
while (!mustStop) {
try {
sleep(cleaningInterval);
} catch (InterruptedException ignore) {
}
if (mustStop) {
break;
}
removeExpired();
}
}
public void halt() {
mustStop = true;
synchronized (this) {
this.interrupt();
}
}
}
}
謝謝Brian。所以我的方法會比有用的更危險,因爲我可以在鏈接的文章中閱讀。我將爲只使用一個DatabaseHelper的方法進行研究。 – Dyonisos
這裏是我寫/使用的包裝,這使得在Android上下文中很好地使用SQLite - [Android的SqlDb](https://github.com/kashifrazzaqui/sqldb) – kashif