2011-12-16 42 views
12

Trong ứng dụng Android của tôi, tôi sử dụng SQLiteOpenHelper để triển khai ContentProvider. Truy vấn, thêm, xóa các hoạt động là tất cả thông qua ContentProvider.Khi nào tôi nên gọi close() trên SQLiteOpenHelper được sử dụng bởi ContentProvider

Nhưng trong một điện thoại Android của tôi (htc g13), tôi tìm thấy tệp * .db-wal trong thư mục/dữ liệu/dữ liệu/[tên gói]/cơ sở dữ liệu. Và kích thước tệp phát sinh rất nhanh khi hoạt động với ContentProvider. Nó chiếm không gian RAM của người dùng quá nhiều.

Bạn nên đóng SQLiteOpenHelper để giải quyết vấn đề của mình (nó hữu ích) trong bài đăng enter link description here.

Nhưng tôi muốn tìm một "địa điểm" để thêm phương thức "close()" vì tôi không trực tiếp sử dụng SQLiteOpenHelper (sử dụng thông qua ContentProvider). phương thức query() trong ContentProvider phải trả về một con trỏ, và SQLiteDatabse sẽ ở trạng thái mở.

Tôi đang bối rối, những gì hiện tôi làm bây giờ để giữ * .db-wal biến mất và sử dụng ContentProvider bình thường?

+2

Đó là một chuỗi cũ nhưng vẫn có liên quan trên Google vì vậy đây là tham chiếu đến câu trả lời chính xác: http: // stackoverflow.com/questions/4547461/close-the-database-in-a-contentprovider – saulobrito

+0

Tôi nghĩ đây là câu trả lời hay nhất, cảm ơn. – cmoaciopm

+0

Đọc Giải thích tuyệt vời này và không cần phải đóng db trong khi sử dụng contentProvider .. http://stackoverflow.com/questions/14002022/android-sq-lite-closed-exception/25379071#25379071 – Nepster

Trả lời

5

Bạn có một vài trường hợp để trang trải:

1) Khi kết thúc ứng dụng của bạn (ví dụ vào onDestroy()) chắc chắn rằng bạn đóng tất cả Cursors, trường hợp cơ sở dữ liệu của SQLiteDatabase và SQLiteOpenHelpers (sử dụng mô hình if (kết nối .isOpen()) object.close())

2) Khi bạn bật lên() -> onResume() - sử dụng các giai đoạn này một cách thích hợp để tạm dừng/tiếp tục kết nối của bạn hoặc đóng/mở chúng.

Thực tiễn tốt là đóng cơ sở dữ liệu của bạn ngay sau khi bạn hoàn thành công việc. Cơ sở dữ liệu được lưu trữ, vì vậy không có vấn đề đóng cửa nó và tái thu Ví dụ một lần nữa khi bạn cần nó với getWritableDatabase()/getReadableDatabase()

Từ doc chính thức: "Một khi đã mở thành công, cơ sở dữ liệu được lưu trữ, Vì vậy, bạn có thể gọi phương thức này mỗi lần bạn cần ghi vào cơ sở dữ liệu (Hãy đảm bảo gọi hàm close() khi bạn không còn cần cơ sở dữ liệu nữa.) "

Cũng lưu ý rằng nếu SQLiteOpenHelper lưu trữ và theo dõi tất cả mở các cá thể của SQLiteDatabase, về cơ bản nó có nghĩa là nếu bạn không để các kết nối cơ sở dữ liệu mở, bạn sẽ không phải gọi gần SQLiteOpenHelper.

Tôi khuyên bạn nên đóng tất cả các con trỏ và cơ sở dữ liệu ngay sau khi bạn ngừng làm việc với chúng. Luôn cố gắng thực thi try/catch/cho các hoạt động truy vấn và cuối cùng chặn để gọi các phương thức đóng trên các đối tượng.

+0

Cảm ơn hovanessyan! Nhưng những gì rắc rối tôi là ứng dụng hỗ trợ đa chủ đề của tôi, tôi không biết "khi" cơ sở dữ liệu thực sự là không cần thiết bởi các ứng dụng. Vấn đề thứ hai là: những gì tôi đang phải đối mặt là ContentProvider (có thể ContentResolver sẽ chính xác), từ điểm thiết kế lớp, tôi không thể lấy tham chiếu của SQLiteDatabase hoặc SQLiteOpenHelpers easilly. Tôi ghét khái niệm ContenProvider! – cmoaciopm

+0

nếu bạn đang sử dụng các luồng riêng biệt cho các cuộc gọi DB, tôi giả sử bạn sẽ sử dụng AsyncTasks. Nếu đó là trường hợp bạn làm tất cả các hoạt động trong doInBackground() và bạn đóng các đối tượng trong onPostExecute(). Tôi không thể hiểu được vấn đề khác. Bạn có thể xây dựng trên điểm thiết kế lớp này không? – hovanessyan

+1

Tôi đã thử logic như gợi ý của bạn, nhưng có ngoại lệ như "cơ sở dữ liệu đã đóng". Tôi nghĩ rằng mã thực hiện seq như dưới đây: 1. thread Một getWritableDatabase(); 2. thread B đóng cơ sở dữ liệu; 3. thread Một truy vấn sql thực thi và ngoại lệ đã xảy ra! – cmoaciopm

6

Kỹ sư khung Android trì hoãn quan điểm này là bạn cần đóng DB.

Theo Dianne Hackborn (Android Khung Engineer) in this thread:

Một nhà cung cấp nội dung được tạo ra khi quá trình lưu trữ của nó được tạo ra, và vẫn quanh càng lâu càng quá trình thực hiện, vì vậy không có nhu cầu để đóng cơ sở dữ liệu - nó sẽ bị đóng như là một phần của hạt nhân làm sạch tài nguyên của quá trình khi quá trình bị giết.

Các vấn đề liên quan