在我的Android应用中,我有以下SQLite接口类
package com.songs.lookup;
import java.util.ArrayList;
import java.util.List;
import com.songs.MainActivity2;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.Context;
import android.database.Cursor;
import android.database.SQLException;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteDatabase.CursorFactory;
import android.database.sqlite.SQLiteOpenHelper;
import android.database.sqlite.SQLiteStatement;
public class CacheDB {
public CacheDB(Context context){
this.dbHelper = new CacheDBHelper(context, DATABASE_NAME, null, DATABASE_VERSION);
}
private Cursor songCursor;
private Cursor tuneCursor;
private Cursor personCursor;
private Context context;
private CacheDBHelper dbHelper;
private SQLiteDatabase db;
private static final String DATABASE_NAME = "SONGS";
private static final int DATABASE_VERSION = 1;
private static final String SONG_TABLE_NAME = "songs";
private static final String TUNE_TABLE_NAME = "tunes";
private static final String PERSON_TABLE_NAME = "persons";
private static final String COLUMN_NAME = "name";
String selectsongQuery = "SELECT * FROM " + SONG_TABLE_NAME;
String selecttuneQuery = "SELECT * FROM " + TUNE_TABLE_NAME;
String selectpersonQuery = "SELECT * FROM " + PERSON_TABLE_NAME;
private static final String SONG_TABLE_CREATE =
"CREATE TABLE " + SONG_TABLE_NAME + " (" +
COLUMN_NAME + " TEXT);";
private static final String TUNE_TABLE_CREATE =
"CREATE TABLE " + TUNE_TABLE_NAME + " (" +
COLUMN_NAME + " TEXT);";
private static final String PERSON_TABLE_CREATE =
"CREATE TABLE " + PERSON_TABLE_NAME + " (" +
COLUMN_NAME + " TEXT);";
class CacheDBHelper extends SQLiteOpenHelper{
SQLiteDatabase readDb = null;
SQLiteDatabase writeDb = null;
public CacheDBHelper(Context context, String name, CursorFactory factory,
int version) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
System.out.println("After the cachedbhelper");
}
@Override
public void onCreate(SQLiteDatabase db) {
System.out.println("Here inside the oncreate of cacheDBHelper");
db.execSQL(SONG_TABLE_CREATE);
db.execSQL(TUNE_TABLE_CREATE);
db.execSQL(PERSON_TABLE_CREATE);
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
}
public SQLiteDatabase getReadDb()
{
if(readDb == null)
readDb = this.getReadableDatabase();
else;
return readDb;
}
public SQLiteDatabase getWriteDb()
{
if(writeDb == null)
writeDb = this.getReadableDatabase();
else;
return writeDb;
}
}
@SuppressLint("NewApi")
public void performOperation(String Operation, String table, ArrayList<String> array1)
{
SQLiteDatabase db = dbHelper.getWriteDb();
String INSERT = "insert into "
+ table + " (" + COLUMN_NAME + ") values (?)";
String DELETE = "delete from " + table;
String FETCH = "select DISTINCT(" + COLUMN_NAME + "from " + table + ")";
db.beginTransaction();
SQLiteStatement dbStmt = db.compileStatement(Operation.equals("INSERT") ? INSERT : DELETE);
if(Operation.equals("INSERT"))
{
int aSize = array1.size();
for (int i = 0; i < aSize; i++) {
dbStmt.bindString(1, array1.get(i));
dbStmt.executeInsert();
}
}
if(Operation.equals("DELETE"))
{
dbStmt.executeUpdateDelete();
}
db.setTransactionSuccessful();
db.endTransaction();
try {
db.close();
dbHelper.close();
} catch (Exception e) {
e.printStackTrace();
}
}
public List<String> fetchData(String table)
{
List<String> result = new ArrayList<String>();
SQLiteDatabase db = this.dbHelper.getReadDb();
result = this.fetchDatafromDB(table, db);
dbHelper.close();
return result;
}
public List<String> fetchDatafromDB(String table, SQLiteDatabase db) {
List<String> list = new ArrayList<String>();
String selectQuery = "SELECT * FROM " + table;
System.out.println("The cursor plac eeee");
if(table == "song")
{
songCursor = db.rawQuery(selectQuery, null);
list = parseCursor(songCursor);
songCursor.close();
}
else if(table == "tune")
{
tuneCursor = db.rawQuery(selectQuery, null);
list = parseCursor(tuneCursor);
tuneCursor.close();
}
else
{
personCursor = db.rawQuery(selectQuery, null);
list = parseCursor(personCursor);
personCursor.close();
}
db.close();
return list;
}
public List<String> parseCursor(Cursor cursor)
{
List<String> list = new ArrayList<String>();
if (cursor.moveToFirst()) {
do {
list.add(cursor.getString(0));
} while (cursor.moveToNext());
}
cursor.close();
return list;
}
}
在另一个我从DB查找数据的类中 我连续为所有三个表调用fetchData方法。第一个表操作正常。但是对于第二个表,我收到以下错误:
04-24 06:27:50.706: E/AndroidRuntime(2354): FATAL EXCEPTION: main
04-24 06:27:50.706: E/AndroidRuntime(2354): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.songs/com.songs.MainActivity2}: java.lang.IllegalStateException: attempt to re-open an already-closed object: SQLiteDatabase: /data/data/com.songs/databases/songS
04-24 06:27:50.706: E/AndroidRuntime(2354): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2059)
04-24 06:27:50.706: E/AndroidRuntime(2354): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2084)
04-24 06:27:50.706: E/AndroidRuntime(2354): at android.app.ActivityThread.access$600(ActivityThread.java:130)
04-24 06:27:50.706: E/AndroidRuntime(2354): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1195)
04-24 06:27:50.706: E/AndroidRuntime(2354): at android.os.Handler.dispatchMessage(Handler.java:99)
04-24 06:27:50.706: E/AndroidRuntime(2354): at android.os.Looper.loop(Looper.java:137)
04-24 06:27:50.706: E/AndroidRuntime(2354): at android.app.ActivityThread.main(ActivityThread.java:4745)
04-24 06:27:50.706: E/AndroidRuntime(2354): at java.lang.reflect.Method.invokeNative(Native Method)
04-24 06:27:50.706: E/AndroidRuntime(2354): at java.lang.reflect.Method.invoke(Method.java:511)
04-24 06:27:50.706: E/AndroidRuntime(2354): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:786)
04-24 06:27:50.706: E/AndroidRuntime(2354): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)
04-24 06:27:50.706: E/AndroidRuntime(2354): at dalvik.system.NativeStart.main(Native Method)
04-24 06:27:50.706: E/AndroidRuntime(2354): Caused by: java.lang.IllegalStateException: attempt to re-open an already-closed object: SQLiteDatabase: /data/data/com.songs/databases/songS
04-24 06:27:50.706: E/AndroidRuntime(2354): at android.database.sqlite.SQLiteClosable.acquireReference(SQLiteClosable.java:55)
04-24 06:27:50.706: E/AndroidRuntime(2354): at android.database.sqlite.SQLiteDatabase.rawQueryWithFactory(SQLiteDatabase.java:1310)
04-24 06:27:50.706: E/AndroidRuntime(2354): at android.database.sqlite.SQLiteDatabase.rawQuery(SQLiteDatabase.java:1253)
04-24 06:27:50.706: E/AndroidRuntime(2354): at com.songs.lookup.CacheDB.fetchDatafromDB(CacheDB.java:181)
04-24 06:27:50.706: E/AndroidRuntime(2354): at com.songs.lookup.CacheDB.fetchData(CacheDB.java:155)
04-24 06:27:50.706: E/AndroidRuntime(2354): at com.songs.lookup.LookUpData.getData(LookUpData.java:38)
04-24 06:27:50.706: E/AndroidRuntime(2354): at com.songs.MainActivity2.onCreate(MainActivity2.java:66)
04-24 06:27:50.706: E/AndroidRuntime(2354): at android.app.Activity.performCreate(Activity.java:5008)
04-24 06:27:50.706: E/AndroidRuntime(2354): at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1079)
04-24 06:27:50.706: E/AndroidRuntime(2354): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2023)
04-24 06:27:50.706: E/AndroidRuntime(2354): ... 11 more
以前有过类似的问题,但我没有看到任何从多个表创建或获取的问题。
基本上是失败的行
personCursor = db.rawQuery(selectQuery, null);
在我使用单个游标并将其初始化为null之前,我认为我需要单独的游标,这可能是问题,但似乎并非如此。
答案 0 :(得分:1)
您在多个地方(db.close()
,dbHelper.close()
,performOperation
)呼叫fetchDataFromDB
和fetchData
。一旦你打电话关闭,你就不能再创建一个全新的DbHelper来查询数据库了。这就是你得到异常的原因,它告诉你数据库已关闭。移除你的近距离通话你应该没问题:你应该在你的活动close
中调用明确的onDestroy
方法。
答案 1 :(得分:0)
请检查您是否输入了错误的表格名称...该表格的名称为“tunes”。在fetchdatafromDB()中,您正在检查名称“tune”。将其更改为“曲调”并更改其他名称。
if(table == "songs")
{
songCursor = db.rawQuery(selectQuery, null);
list = parseCursor(songCursor);
songCursor.close();
}
希望它有所帮助。