2013-04-26 2 views
0

В моей Android приложений, у меня есть следующие SQLite интерфейса класса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); 

До меня был один курсор и инициализируются его обнулить, а затем подумал, что мне нужно отдельные курсоры, которые могли бы стать проблемой, но это, кажется, не это так.

ответ

1

Вы звоните db.close() и dbHelper.close() в нескольких местах (performOperation, fetchDataFromDB, fetchData). После того, как вы позвоните, вы больше не можете запрашивать базу данных, не создавая новый DbHelper. Вот почему вы получаете исключение, которое говорит вам, что база данных закрыта. Удалите свои закрытые вызовы, и все должно быть в порядке: должен быть установлен явный метод close, который вы вызываете в своей деятельности onDestroy.

+0

Это z right Femi ... – DGN

+0

Я пробовал исправления, которые вы упомянули, и я больше не получаю трассировку стека. Я удалил все закрытые утверждения, и теперь он отлично работает. Но теперь, когда я выключаю устройство и включаю его без запуска сервера, я получаю ошибку в следующих строках: следующая строка после dbStmt.executeInsert(); и ошибка вызвана: java.lang.NullPointerExceptionat android.database.sqlite.SQLiteOpenHelper.getDatabaseLocked (SQLiteOpenHelper.java:224) в android.database.sqlite.SQLiteOpenHelper.getReadableDatabase (SQLiteOpenHelper.java:188) –

+0

Не совсем уверен без полной трассировки стека, но либо вы, вероятно, не называете 'close()', как вы должны быть (вы должны называть 'close()' из 'onDestroy' вашей активности) или вы передаете недопустимый контекст в помощник , как действие, которое больше не действует. – Femi

0

Проверьте, не указали ли вы имена таблиц ... Таблица создана с именами «мелодии». В fetchdatafromDB() вы проверяете имя «tune». Измените его на «мелодии» и измените и другие имена.

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

Надеюсь, это поможет.

+0

Существует три разных таблицы. Не уверен, о чем вы говорите. –

Смежные вопросы