Nếu bạn nhận được thông báo cho biết có quá nhiều tệp đang mở, nguyên nhân có thể là do có quá nhiều Con trỏ vẫn đang mở.
Tuy nhiên, thông báo trả về có thể không phải lúc nào cũng giống nhau và có thể dành riêng cho tác vụ / cuộc gọi đang được gọi.
Trong trường hợp này, thông báo là (unable to open database file (code 2062))
, nhưng trong một trường hợp khác (từ một SELECT, thông báo unable to open database file (code 14)
). SQLite không thể mở tệp cơ sở dữ liệu (mã 14) trên truy vấn "CHỌN" thường xuyên.
Liên kết trên cũng trỏ đến một bài đăng mà tôi đã thực hiện cho thấy khá rõ ràng rằng việc tạo Con trỏ dẫn đến một tệp (hoặc các tệp) được mở.
Ví dụ này lặp lại khoảng 500 hàng và đối với mỗi hàng, nó đang tạo / tạo lại 3 con trỏ cho mỗi hàng (vì vậy có khả năng hơn 1500 con trỏ mặc dù chỉ sử dụng 4 đối tượng con trỏ).
Ban đầu, nó chỉ đóng 3 con trỏ ở cuối (hàng cuối cùng của tất cả) dẫn đến unable to open database File (code 14)
. Việc đóng 3 con trỏ cho mỗi lần lặp lại đã giải quyết được sự cố.
Mã không thành công là:-
SQLiteDatabase db = getWritableDatabase();
Cursor shoplistcursor = getAllRowsFromTable(SHOPLIST_TABLE_NAME);
Cursor productcsr;
Cursor aislecsr;
Cursor prdusecsr;
while(shoplistcursor.moveToNext()) {
productcsr = getProductFromProductId(shoplistcursor.getLong(shoplistcursor.getColumnIndex(SHOPLIST_COLUMN_PRODUCTREF)));
aislecsr = getAisleFromAisleId(shoplistcursor.getLong(shoplistcursor.getColumnIndex(SHOPLIST_COLUMN_AISLEREF)));
prdusecsr = getProductUsage(shoplistcursor.getLong(shoplistcursor.getColumnIndex(SHOPLIST_COLUMN_AISLEREF)),
shoplistcursor.getLong(shoplistcursor.getColumnIndex(SHOPLIST_COLUMN_PRODUCTREF)));
if (productcsr.getCount() < 1 | aislecsr.getCount() < 1 | prdusecsr.getCount() < 1) {
deleteShopListEntry(shoplistcursor.getLong(shoplistcursor.getColumnIndex(SHOPLIST_COLUMN_ID)));
}
if(shoplistcursor.isLast()) {
prdusecsr.close();
aislecsr.close();
productcsr.close();
}
}
shoplistcursor.close();
db.close();
}
Trong khi mã cố định là:-
SQLiteDatabase db = getWritableDatabase();
Cursor shoplistcursor = getAllRowsFromTable(SHOPLIST_TABLE_NAME);
Cursor productcsr;
Cursor aislecsr;
Cursor prdusecsr;
while(shoplistcursor.moveToNext()) {
productcsr = getProductFromProductId(shoplistcursor.getLong(shoplistcursor.getColumnIndex(SHOPLIST_COLUMN_PRODUCTREF)));
aislecsr = getAisleFromAisleId(shoplistcursor.getLong(shoplistcursor.getColumnIndex(SHOPLIST_COLUMN_AISLEREF)));
prdusecsr = getProductUsage(shoplistcursor.getLong(shoplistcursor.getColumnIndex(SHOPLIST_COLUMN_AISLEREF)),
shoplistcursor.getLong(shoplistcursor.getColumnIndex(SHOPLIST_COLUMN_PRODUCTREF)));
if (productcsr.getCount() < 1 | aislecsr.getCount() < 1 | prdusecsr.getCount() < 1) {
productcsr.close();
aislecsr.close();
prdusecsr.close();
deleteShopListEntry(shoplistcursor.getLong(shoplistcursor.getColumnIndex(SHOPLIST_COLUMN_ID)));
} else {
productcsr.close();
aislecsr.close();
prdusecsr.close();
}
}
shoplistcursor.close();
db.close();
}
Bây giờ tôi có xu hướng tuân theo quy tắc / thông lệ sau:-
-
Nếu chỉ nhận được kết quả, v.d. lấy số hàng, đóng Con trỏ trong phương thức.
-
Nếu sử dụng Con trỏ cho màn hình, ví dụ:một ListView, sau đó đóng con trỏ trong
onDestroy
của hoạt động phương pháp. -
Nếu sử dụng Con trỏ cho những gì tôi sẽ gọi là xử lý phức tạp hơn, ví dụ:xóa các hàng có tham chiếu bên dưới, sau đó đóng con trỏ ngay sau khi chúng được thực hiện xong, trong (các) vòng lặp xử lý.