0

在我的 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; 
  }

}

在另一个我正在从数据库中查找数据的类中,我正在为所有三个表连续调用 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);

在我有一个游标并将其初始化为空之前,然后认为我需要单独的游标,这可能是问题,但似乎并非如此。

4

2 回答 2

1

您在多个地方 ( , db.close(), )打电话。调用 close 后,如果不创建全新的 DbHelper,您将无法再查询数据库。这就是您收到异常的原因,它告诉您数据库已关闭。删除您的近距离通话,您应该没问题:应该有一个明确的方法可以在您的 Activity 中调用。dbHelper.close()performOperationfetchDataFromDBfetchDatacloseonDestroy

于 2013-04-26T03:51:23.070 回答
0

Please check whether you have mistyped the table names... The table is created with names "tunes". In fetchdatafromDB(), you are checking with the name "tune". Change it to "tunes" and change the other names also.

  if(table == "songs")
   {
     songCursor = db.rawQuery(selectQuery, null);
     list = parseCursor(songCursor);
     songCursor.close();
   }

Hope it helps.

于 2013-04-26T04:52:07.323 回答