【发布时间】:2020-10-20 02:14:18
【问题描述】:
在我的 Android 应用程序中,我有一些使用 SQLite 的数据库事务,但是尽管尝试了多种方法来防止泄漏,但我还是遇到了 SQLiteConnection 对象泄漏。我几乎尝试过互联网上的每一件事,比如关闭数据库、关闭游标或结束事务。以下是android studio中的警告。
数据库“/data/user/0/com.example.myapp/databases/myapp.dbnotes.db”的 SQLiteConnection 对象被泄露!请修复您的应用程序以正确结束正在进行的事务并在不再需要时关闭数据库。
有时通过关闭数据库或关闭我曾经得到错误的游标 -
Attempt to reopen an already-closed object ....。我不是Android专业人士,我正在尝试自己学习,所以你能帮助我吗?我已经发布了以下代码:
-
在 DBHelper 类中
public class DBHelper extends SQLiteOpenHelper { ... public static DBHelper getInstance(Context ctx) { if (mInstance == null) { mInstance = new DBHelper(ctx.getApplicationContext()); } return mInstance; } private DBHelper(Context context) { super(context, DB_NAME, null, 1); this.context = context; DB_PATH = context.getDatabasePath(DB_NAME).getPath(); } ... private Cursor getData(String Query) { String myPath = DB_PATH + DB_NAME; Cursor c = null; try { db = SQLiteDatabase.openDatabase(myPath, null, SQLiteDatabase.OPEN_READWRITE); c = db.rawQuery(Query, null); } catch (Exception e) { e.printStackTrace(); } return c; } private void dml(String Query) { String myPath = DB_PATH + DB_NAME; if (db == null) db = SQLiteDatabase.openDatabase(myPath, null, SQLiteDatabase.OPEN_READWRITE); try { db.execSQL(Query); } catch (Exception e) { e.printStackTrace(); } } //Methods to perform different db transaction public void addToSubject(ItemSubject itemSubject) { if (checkSuggested(itemSubject.getId())) { dml("delete from " + TABLE_SUBJECT + " where id = '" + itemSubject.getId() + "'"); } String insert = "insert into TABLE_SUBJECT ....."; dml(insert); } public void cleartable_subject() { String delete = "delete from " + TABLE_SUBJECT; dml(delete); } public long subject_size() { if (db == null) { db = SQLiteDatabase.openDatabase(DB_PATH + DB_NAME, null, SQLiteDatabase.OPEN_READWRITE); } try { long count = DatabaseUtils.queryNumEntries(db, TABLE_SUBJECT); return count; } catch (Exception e) { e.printStackTrace(); return 0; } } private Boolean checkSubject(String id) { String select = "select * from " + TABLE_SUBJECT + " where id = '" + id + "'"; Cursor cursor = getData(select); return cursor != null && cursor.getCount() > 0; } public ArrayList<ItemSubject> loadDataSubject() { ArrayList<ItemSubject> arrayList = new ArrayList<>(); String select = "select * from " + TABLE_SUBJECT; Cursor cursor = getData(select); if (cursor != null && cursor.getCount() > 0) { cursor.moveToFirst(); for (int i = 0; i < cursor.getCount(); i++) { String id = cursor.getString(cursor.getColumnIndex(TAG_ID)); String course = cursor.getString(cursor.getColumnIndex(TAG_COURSE_NAME)); .... ItemSubject objItem = new ItemSubject(id, courseId,...); arrayList.add(objItem); cursor.moveToNext(); } cursor.close(); } return arrayList; } //There are more similar methods for other tables
我正在片段和活动中访问这些方法,例如
dbHelper = DBHelper.getInstance(getActivity());
if ((dbHelper.subject_size() >= 1){
dbHelper.cleartable_subject();
for (int i = 0; i < arrayListSubject.size(); i++) {
dbHelper.addToSubject(arrayListSubject.get(i));
}
arrayListSubject = dbHelper.loadDataSubject();
}
很抱歉,代码很长,但我认为一切都是必要的。你能帮帮我吗?
【问题讨论】:
标签: java android memory-leaks android-sqlite