填充ListView时SQLite db关闭问题

时间:2012-12-11 13:38:12

标签: android sqlite listview

我将预先存在的数据库复制到新创建的数据库后出现错误,该数据库用于填充带标题的列表视图。一切正常,但是一旦滚动列表视图,我就会收到关于数据库未被关闭的错误。

我无法确定在何处发表密切声明。我已经在我的活动超类的onDestroy()方法中添加了每次使用游标填充用于列表视图的数组时打开和关闭数据库。

我在这里查看了其他问题,但我似乎找不到这个特定问题的答案。

非常感谢

继承logcat:

12-11 12:55:58.072: E/Database(17830): close() was never explicitly called on database  '/data/data/com.sil.android.bofseg2012/databases/bofsegdb1' 
12-11 12:55:58.072: E/Database(17830): android.database.sqlite.DatabaseObjectNotClosedException: Application did not close the cursor or database object that was opened here
12-11 12:55:58.072: E/Database(17830):  at android.database.sqlite.SQLiteDatabase.<init>(SQLiteDatabase.java:1810)
12-11 12:55:58.072: E/Database(17830):  at android.database.sqlite.SQLiteDatabase.openDatabase(SQLiteDatabase.java:817)
12-11 12:55:58.072: E/Database(17830):  at com.sil.android.bofseg2012.DBHelper.openDatabase(DBHelper.java:108)
12-11 12:55:58.072: E/Database(17830):  at com.sil.android.bofseg2012.DBHelper.getDatabase(DBHelper.java:121)
12-11 12:55:58.072: E/Database(17830):  at com.sil.android.bofseg2012.GamesList.<init>(GamesList.java:55)
12-11 12:55:58.072: E/Database(17830):  at com.sil.android.bofseg2012.ContentsActivity.populateLists(ContentsActivity.java:49)
12-11 12:55:58.072: E/Database(17830):  at com.sil.android.bofseg2012.ContentsActivity.onResume(ContentsActivity.java:102)
12-11 12:55:58.072: E/Database(17830):  at android.app.Instrumentation.callActivityOnResume(Instrumentation.java:1149)
12-11 12:55:58.072: E/Database(17830):  at android.app.Activity.performResume(Activity.java:3823)

这是我的dbOpenHelper类:

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

import android.content.ContentValues;
import android.content.Context;
import android.database.SQLException;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;

public class DBHelper extends SQLiteOpenHelper
{
    private static final String DB_PATH = "/data/data/com.sil.android.bofseg2012/databases/";
    private static final String DB_NAME = "bofsegdb1";
    private static final int VERSION = 1;
    private static final String TABLE_NAME = "bofseg_full_1";
    protected static final String SEARCHABLE_TABLE = "searchable_table";
    private static final String KEY_ID = "_id";
    private static final String GAME_NAME = "game_name";
    private static final String PLAYERS = "players";
    private static final String VENUE = "venue";
    private static final String DURATION = "duration";
    private static final String EQUIPMENT = "equipment";
    private static final String SECTION = "section";
    private static final String FAVES = "fave";
    private SQLiteDatabase myDB;
    private final Context dbContext;

    public DBHelper(Context context)
    {
        super(context, DB_NAME, null, VERSION);
        this.dbContext=context; 
    }

    // check the imported database exists
    private boolean checkDatabase()
    {
        File dbFile = new File(DB_PATH + DB_NAME);
        boolean dbExists = dbFile.exists();
        return dbExists;
    }

    private void createAndCopyDataBase() throws IOException
    {
        if(!this.checkDatabase())
        {
            try
            {
                this.getWritableDatabase();

            } catch (Exception e1)
            {
                System.out.println("Error creating system db");
                e1.printStackTrace();
            }

            try
            {
                this.copyDatabase();
                //System.out.println("db copied");
            }catch(IOException e)
            {
                throw new Error("Error copying database");
            }
            finally
            {
                try
                {
                    this.close();
                } catch (Exception e)
                {               
                    e.printStackTrace();
                }
            }
            System.out.println("DB created and copied  and closed successfully");
        }
    }


    private void copyDatabase() throws IOException
    {
            InputStream myInput = dbContext.getAssets().open(DB_NAME);
            String outFileName = DB_PATH + DB_NAME;
            OutputStream myOutput = new FileOutputStream(outFileName);
            byte[] buffer = new byte[1024];
            int length;
            while((length = myInput.read(buffer))>0)
            {
                myOutput.write(buffer,0,length);
            }
            myOutput.flush();
            myOutput.close();
            myInput.close();        

            this.createVirtualTable();
            this.getDatabase().execSQL("INSERT INTO " + SEARCHABLE_TABLE  + " SELECT * FROM " + TABLE_NAME);
            this.close();

    }

    public void openDatabase() throws SQLException
    {
        String sysDBPath = DB_PATH + DB_NAME;
            // this is line 108 that is throwing the error:
        this.myDB = SQLiteDatabase.openDatabase(sysDBPath, null, SQLiteDatabase.OPEN_READWRITE);
        System.out.println("DBH openDatabase myDB is open = " + this.myDB.isOpen());
    }

    public SQLiteDatabase getDatabase()
    { 
        try
        {
            this.createAndCopyDataBase();
        } catch (IOException e)
        {
            e.printStackTrace();
        }
        this.openDatabase();

        return this.myDB;
    }

    private void createVirtualTable()
    {
        try
        {
            this.getDatabase().execSQL("CREATE VIRTUAL TABLE ["+SEARCHABLE_TABLE+"] USING fts3 (" +
                    "[" +KEY_ID+"] TEXT," +
                    "[" +GAME_NAME+"] TEXT," +
                    "[" +PEOPLE+"] TEXT," +
                    "[" +VENUE+"] TEXT," +
                    "[" +DURATION +"] TEXT," +
                    "[" +EQUIPMENT +"] TEXT," +
                    "[" +SECTION +"] TEXT," +
                    "[" +FAVES+"] TEXT," +");"
                    );
            System.out.println("virtual table created");
        }
        catch (Exception e)
        {
            e.printStackTrace();
            this.deleteSearchableDBStructure(this.getDatabase());
        }

    }

    private void deleteSearchableDBStructure(SQLiteDatabase database)
    {
        try
        {
            database.execSQL("DROP TABLE IF EXISTS ["+SEARCHABLE_TABLE+"];");
        } catch (SQLException e)
        {           
            e.printStackTrace();
        }
    }


    public synchronized void close()
    {
                try
                {
                    this.myDB.close();
                    super.close();
                    System.out.println("myDb is open = " + this.myDB.isOpen());
                } catch (Exception e)
                {
                    System.out.println("Error in DBHelper close()");
                    e.printStackTrace();
                }
    }

    //Update the faves column of the db at row pageNumber
    public boolean addFavourite(int pageNumber)
    {
        boolean addedOk = false;
        ContentValues args = new ContentValues();

        try
        {
            args.put(FAVES, "y");
            this.openDatabase();
            this.myDB.update(TABLE_NAME, args, KEY_ID + " = " + pageNumber , null);
            addedOk = true;
        } catch (SQLException e)
        {       
            e.printStackTrace();
        }
        finally{
            try
            {
                this.close();
            }
            catch (Exception e) {
                e.printStackTrace();
            }

        }
        return addedOk;
    }

    @Override
    public void onCreate(SQLiteDatabase db)
    {

    }

    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion)
    {
    }


}

1 个答案:

答案 0 :(得分:0)

我认为您在更新后将其保持打开状态。也许在this.myDB.close();之后添加addedOk = true;可能有帮助