我有一个 android 服务,试图从中访问 sqlite 数据库。代码运行正常,但无法访问数据库。我认为错误与数据库锁定有关。这是我访问数据库的方法:
private void checkWatchList() {
Log.i("watch list", "watch list started");
Cursor cursor;
try {
cursor = dbhandler.getAlerts();
if (cursor.moveToFirst()) {
while (cursor.moveToNext()) {
Log.i("watch list", "checked");
String share_name = cursor.getString(cursor
.getColumnIndex(KEY_SHARE_NAME));
String max_price = cursor.getString(cursor
.getColumnIndex(KEY_MAX_PRICE));
String min_price = cursor.getString(cursor
.getColumnIndex(KEY_MIN_PRICE));
int action = cursor.getInt(cursor
.getColumnIndex(KEY_ACTION));
if (min_price.equals("NULL")) {
double maxprice = Double.parseDouble(max_price);
compareMax(share_name, maxprice, action);
} else if (max_price.equals("NULL")) {
double minprice = Double.parseDouble(min_price);
compareMin(share_name, minprice, action);
} else {
double maxprice = Double.parseDouble(max_price);
double minprice = Double.parseDouble(min_price);
compareMinMax(share_name, minprice, maxprice, action);
}
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
private void compareMin(String sharename, double minprice, int action) {
Log.i("compare min", "compare min");
Cursor cursor;
double new_price;
String message = "The price is below minimum set price";
try {
cursor = dbhandler.compare(sharename);
new_price = cursor.getDouble(cursor.getColumnIndex(KEY_PRICE));
if (minprice <= new_price) {
dbhandler.addTask(sharename, action, message);
}
} catch (Exception e) {
e.printStackTrace();
}
}
private void compareMinMax(String sharename, double minprice,
double maxprice, int action) {
Log.i("compare minmax", "compare minmax");
Cursor cursor;
String message = "This price is below minimum set price.";
try {
cursor = dbhandler.compare(sharename);
double new_price = cursor.getDouble(cursor
.getColumnIndex(KEY_PRICE));
if (new_price <= minprice) {
dbhandler.addTask(sharename, action, message);
} else if (new_price >= maxprice) {
dbhandler.addTask(sharename, action, message);
}
} catch (Exception e) {
e.printStackTrace();
}
}
private void compareMax(String sharename, double maxprice, int action) {
Log.i("compare max", "compare max");
Cursor cursor;
String message = "This price is more than maximum set price.";
try {
cursor = dbhandler.compare(sharename);
double new_price = cursor.getDouble(cursor
.getColumnIndex(KEY_PRICE));
if (new_price >= maxprice) {
dbhandler.addTask(sharename, action, message);
}
} catch (Exception e) {
e.printStackTrace();
}
}
这是来自 DatabaseHandler 类的方法:
public Cursor getAlerts() {
Cursor cursor;
SQLiteDatabase database = this.getReadableDatabase();
cursor = database.query(TABLE_ALERTS, new String[] { KEY_SHARE_NAME,
KEY_MIN_PRICE, KEY_MAX_PRICE, KEY_ACTION }, null, null, null,
null, null);
database.close();
return cursor;
}
public void addTask(String name, int action, String message) {
SQLiteDatabase database = this.getWritableDatabase();
ContentValues values = new ContentValues();
values.put(KEY_SHARENAME, name);
values.put(KEY_TASK, action);
values.put(KEY_MESSAGE, message);
database.insert(TABLE_TASKS, null, values);
database.close();
}
public Cursor compare(String sharename) {
Cursor cursor;
SQLiteDatabase database = this.getReadableDatabase();
cursor = database.query(TABLE_SHARES, new String[] { KEY_PRICE },
KEY_NAME + "=?", new String[] { sharename }, null, null, null);
database.close();
return cursor;
}
从 logcat 的输出来看,我的代码一直运行到 checkWatchList 方法,但没有执行循环中的 if 条件。这是 logcat 输出
09-11 13:11:15.289: I/watch list(22091): watch list started
09-11 13:11:15.319: W/System.err(22091): java.lang.IllegalStateException: database /data/data/com.intelligent.stocktrader/databases/stocktrader.db (conn# 0) already closed
09-11 13:11:15.329: W/System.err(22091): at android.database.sqlite.SQLiteDatabase.verifyDbIsOpen(SQLiteDatabase.java:2082)
09-11 13:11:15.329: W/System.err(22091): at android.database.sqlite.SQLiteDatabase.lock(SQLiteDatabase.java:413)
09-11 13:11:15.329: W/System.err(22091): at android.database.sqlite.SQLiteDatabase.lock(SQLiteDatabase.java:400)
09-11 13:11:15.329: W/System.err(22091): at android.database.sqlite.SQLiteQuery.fillWindow(SQLiteQuery.java:79)
09-11 13:11:15.339: W/System.err(22091): at android.database.sqlite.SQLiteCursor.fillWindow(SQLiteCursor.java:160)
09-11 13:11:15.339: W/System.err(22091): at android.database.sqlite.SQLiteCursor.getCount(SQLiteCursor.java:152)
09-11 13:11:15.339: W/System.err(22091): at android.database.AbstractCursor.moveToPosition(AbstractCursor.java:158)
09-11 13:11:15.349: W/System.err(22091): at android.database.AbstractCursor.moveToFirst(AbstractCursor.java:235)
09-11 13:11:15.349: W/System.err(22091): at com.intelligent.stocktrader.database.ShareService.checkWatchList(ShareService.java:160)
09-11 13:11:15.349: W/System.err(22091): at com.intelligent.stocktrader.database.ShareService.onCreate(ShareService.java:63)
09-11 13:11:15.359: W/System.err(22091): at android.app.ActivityThread.handleCreateService(ActivityThread.java:2252)
09-11 13:11:15.359: W/System.err(22091): at android.app.ActivityThread.access$1600(ActivityThread.java:122)
09-11 13:11:15.359: W/System.err(22091): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1200)
09-11 13:11:15.369: W/System.err(22091): at android.os.Handler.dispatchMessage(Handler.java:99)
09-11 13:11:15.369: W/System.err(22091): at android.os.Looper.loop(Looper.java:137)
09-11 13:11:15.369: W/System.err(22091): at android.app.ActivityThread.main(ActivityThread.java:4340)
09-11 13:11:15.369: W/System.err(22091): at java.lang.reflect.Method.invokeNative(Native Method)
09-11 13:11:15.379: W/System.err(22091): at java.lang.reflect.Method.invoke(Method.java:511)
09-11 13:11:15.379: W/System.err(22091): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:784)
09-11 13:11:15.379: W/System.err(22091): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:551)
09-11 13:11:15.379: W/System.err(22091): at dalvik.system.NativeStart.main(Native Method)
09-11 13:11:15.389: I/LocalService(22091): Received start id 1: Intent { cmp=com.intelligent.stocktrader/.database.ShareService }