База данных Sqlite УТВЕРЖДАЕТ исключение в Android? - PullRequest
5 голосов
/ 17 февраля 2010

Я получаю это исключение в базе данных Leak Found

my LOGCAT Показывает это:

02-17 17:20:37.857: INFO/ActivityManager(58): Starting activity: Intent { cmp=com.example.brown/.Bru_Bears_Womens_View (has extras) }
02-17 17:20:38.477: DEBUG/dalvikvm(434): GC freed 1086 objects / 63888 bytes in 119ms
02-17 17:20:38.556: ERROR/Database(434): Leak found
02-17 17:20:38.556: ERROR/Database(434): java.lang.IllegalStateException: /data/data/com.example.brown/databases/BRUNEWS_DB_01.db SQLiteDatabase created and never closed
02-17 17:20:38.556: ERROR/Database(434):     at android.database.sqlite.SQLiteDatabase.<init>(SQLiteDatabase.java:1694)
02-17 17:20:38.556: ERROR/Database(434):     at android.database.sqlite.SQLiteDatabase.openDatabase(SQLiteDatabase.java:738)
02-17 17:20:38.556: ERROR/Database(434):     at android.database.sqlite.SQLiteDatabase.openOrCreateDatabase(SQLiteDatabase.java:760)
02-17 17:20:38.556: ERROR/Database(434):     at android.database.sqlite.SQLiteDatabase.openOrCreateDatabase(SQLiteDatabase.java:753)
02-17 17:20:38.556: ERROR/Database(434):     at android.app.ApplicationContext.openOrCreateDatabase(ApplicationContext.java:473)
02-17 17:20:38.556: ERROR/Database(434):     at android.content.ContextWrapper.openOrCreateDatabase(ContextWrapper.java:193)
02-17 17:20:38.556: ERROR/Database(434):     at android.database.sqlite.SQLiteOpenHelper.getWritableDatabase(SQLiteOpenHelper.java:98)
02-17 17:20:38.556: ERROR/Database(434):     at com.example.brown.Brown_Splash.onCreate(Brown_Splash.java:52)
02-17 17:20:38.556: ERROR/Database(434):     at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1047)
02-17 17:20:38.556: ERROR/Database(434):     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2459)
02-17 17:20:38.556: ERROR/Database(434):     at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2512)
02-17 17:20:38.556: ERROR/Database(434):     at android.app.ActivityThread.access$2200(ActivityThread.java:119)
02-17 17:20:38.556: ERROR/Database(434):     at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1863)
02-17 17:20:38.556: ERROR/Database(434):     at android.os.Handler.dispatchMessage(Handler.java:99)
02-17 17:20:38.556: ERROR/Database(434):     at android.os.Looper.loop(Looper.java:123)
02-17 17:20:38.556: ERROR/Database(434):     at android.app.ActivityThread.main(ActivityThread.java:4363)
02-17 17:20:38.556: ERROR/Database(434):     at java.lang.reflect.Method.invokeNative(Native Method)
02-17 17:20:38.556: ERROR/Database(434):     at java.lang.reflect.Method.invoke(Method.java:521)
02-17 17:20:38.556: ERROR/Database(434):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:860)
02-17 17:20:38.556: ERROR/Database(434):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:618)
02-17 17:20:38.556: ERROR/Database(434):     at dalvik.system.NativeStart.main(Native Method)

как я могу это решить ???

спасибо заранее ...

Ответы [ 3 ]

10 голосов
/ 17 февраля 2010

Вы должны закрыть свою базу данных

public DBAdapter open() throws SQLException 
{
    db = DBHelper.getWritableDatabase();
    return this;
}

//---closes the database---    
public void close() 
{
    DBHelper.close();
}

http://www.devx.com/wireless/Article/40842/1763?supportItem=4

7 голосов
/ 16 марта 2010

Вам необходимо либо закрыть объект базы данных, либо удерживать объект базы данных, чтобы в вашем поставщике контента была переменная, ссылающаяся на объект базы данных, позволяющая при сборке мусора игнорировать открытую базу данных.

Проблема с закрытием базы данных в поставщике контента заключается в том, что курсор, возвращаемый к действию, которое запросило запрос, становится пустым курсором.

Таким образом, выбор заключается в том, чтобы либо навсегда удерживать открытый объект базы данных (время жизни провайдера контента), либо убедиться, что база данных закрыта, когда курсор закрыт.

Я выбрал второй вариант и получил курсор, расширив класс SQLiteCursor и реализовав интерфейс SQLiteDatabase.CursorFactory со следующим кодом:

public class MyCursor extends SQLiteCursor
{
    final  SQLiteDatabase mDatabase;
    final  int            mID;


    public MyCursor(SQLiteDatabase      database,
                     SQLiteCursorDriver  driver,
                     String              table,
                     SQLiteQuery         query,
                     int                 cursorID)
    {
        super(database, driver, table, query);

        mDatabase = database;
        mID       = cursorID;
    }

    /**
     * Closes the database used to generate the cursor when the
     * cursor is closed.  Hopefully, plugging the GC Leak detected
     * when using pure SQLiteCursor that are wrapped when returned
     * to an Activity and therefore unreachable.
     */
    @Override
    public void close()
    {
        super.close();
        if ( mDatabase != null )
        {
            mDatabase.close();
        }
    }

    /**
     * Closes cursor without closing database.
     */
    public void closeForReuse()
    {
        super.close();
    }

    @Override
    public String toString()
    {
        return super.toString() + ", ID# " + mID;
    }

}   // end of MyCursor class


//========================================================================
// Nested Class to create the MyCursor for queries

class MyCursorFactory implements SQLiteDatabase.CursorFactory
{
    /**
     * Creates and returns a new Cursor of MyCursor type.
     */
    public Cursor newCursor ( SQLiteDatabase      database,
                              SQLiteCursorDriver  driver,
                              String              editTable,
                              SQLiteQuery         query )
    {
        int  cursorID = MyProvider.CursorID++;

        return new MyCursor(database,
                            driver,
                            editTable,
                            query,
                            cursorID);
    }

}   // end of MyCursorFactory class

Этот код предоставляет объект курсора, который закрывает базу данных, когда сам курсор закрыт, разрешая исключение IllegalStateException во время сборки мусора. Это накладывает ответственность за закрытие курсора на активность, которая его запросила. Это не должно создавать дополнительную нагрузку на действие, так как закрытие курсора, когда оно выполнено, является хорошей практикой.

Эти два класса вложены в MyProvider, мой класс контент-провайдера, и элемент данных CursorID инициализируется MyProvider.

2 голосов
/ 28 марта 2011

Просто убедитесь, что вы всегда закрываете свой Помощник по БД перед выходом из действия.

db.close();
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...