我在数据库Leak Found
中收到此异常我的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)
我该如何解决?
提前感谢...
答案 0 :(得分:10)
您必须关闭数据库
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
答案 1 :(得分:7)
您需要关闭数据库对象或保留数据库对象,以便Content Provider中有一个引用数据库对象的变量,允许垃圾收集忽略打开的数据库。
在内容提供程序中关闭数据库的问题是返回到请求查询的活动的游标变为空游标。
因此,选择是永远保持打开的数据库对象(Content Provider的生命周期),或者确保在光标关闭时关闭数据库。
我选择了第二个选项并通过扩展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 :(得分:2)
请确保在退出活动之前始终关闭数据库助手。
db.close();