2013-04-26 24 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; 
    } 

} 

在另一大類,其中我從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 

已經有它們similiar以前的問題,但我還沒有看到它創建或從多個表中獲取任何這樣的問題。

本質上它是失敗的

 personCursor = db.rawQuery(selectQuery, null); 

之前,我有一個單光標線,並初始化爲null,然後認爲我需要獨立的光標這可能是問題,但它似乎沒有不是這樣的。

回答

1

你調用在多個地方(performOperationfetchDataFromDBfetchDatadb.close()dbHelper.close()。一旦你致電關閉,你不能再創建一個全新的DbHelper查詢數據庫。這就是爲什麼你會得到異常,這會告訴你數據庫已關閉。刪除你的近距離通話,你應該沒問題:你應該在你的活動onDestroy中調用一個明確的close方法。

+0

這z正確的費米... – DGN 2013-04-26 04:54:31

+0

我試過你提到的修復,我沒有得到任何更多的堆棧跟蹤。我刪除了所有關閉語句,現在它工作正常。但現在,當我關閉設備並在沒有運行服務器的情況下將其打開時,出現以下錯誤:dbStmt.executeInsert()之後的下一行;並且錯誤是由於:android.database.sqlite.SQLiteOpenHelper.getReadableDatabase(SQLiteOpenHelper.java:188) – 2013-04-29 04:55:51

+0

不太確定沒有完整的堆棧跟蹤,但是要麼你可能不會像你應該那樣調用close()(你應該從你的activity的onDestroy中調用close()),或者你將一個無效的上下文傳遞給了helper ,就像一個不再有效的活動一樣。 – Femi 2013-04-29 05:12:31

0

請檢查您是否錯誤輸入了表格名稱...表格是使用名稱「tunes」創建的。在fetchdatafromDB()中,您正在使用名稱「tune」進行檢查。將其更改爲「曲調」並更改其他名稱。

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

希望它有幫助。

+0

有三個不同的表格。不知道你在說什麼。 – 2013-04-26 05:28:38