2017-07-28 46 views
5

Khi sử dụng phòng từ các kiến ​​trúc Components Android, tôi nhận được lỗi sau khi cố gắng truy cập vào cơ sở dữ liệu sử dụng một thành phần Dagger:Phòng nỗ lực để mở lại một cơ sở dữ liệu đã đóng

java.lang.IllegalStateException: attempt to re-open an already-closed object: SQLiteDatabase: (database path) 

Tôi đã sử dụng phiên bản Dagger 2.11 và phiên bản Phòng 1.0.0-alpha7. Lỗi này có thể sao chép được trên phiên bản 1.0.0-alpha5.

Lỗi này xảy ra khi có bất kỳ nỗ lực nào truy cập cơ sở dữ liệu thông qua DAO sau khi khởi tạo cơ sở dữ liệu và đưa nó vào lớp của tôi.

Trả lời

19

Đó là bởi vì bạn đang cố gắng để thay đổi giản đồ cơ sở dữ liệu hiện có mà không đưa ra bất kỳ thông tin di chuyển nào. Vì vậy, về cơ bản nó cố gắng để viết lược đồ cơ sở dữ liệu mới cho DB hiện tại mà không hoạt động.

Có hai cách để giải quyết vấn đề này. Nếu bạn đang ở trong môi trường phát triển của bạn những gì bạn có thể làm là dự phòng để một di dân phá hoại, để làm mã tạo cơ sở dữ liệu của bạn này sẽ trông giống như sau:

MyDatabase myDatabase = Room.databaseBuilder(context, MyDatabase.class, "my-db") 
    .fallbackToDestructiveMigration() 
    .build(); 

Điều này có nghĩa khi bạn cung cấp cơ sở dữ liệu với một cập nhật hoặc thực thể mới nó sẽ làm những gì các câu trả lời từ @huw cho biết và chỉ cần xóa cơ sở dữ liệu trên cài đặt của ứng dụng loại bỏ tất cả các dữ liệu từ nó và cung cấp cho bạn một cài đặt mới.

Phương pháp khác là sử dụng chức năng di chuyển. Họ là khá dài vì vậy trừ khi ai đó muốn tôi viết nó lên đây, tôi sẽ để nó cho bây giờ nhưng về cơ bản, các tài liệu có thể được tìm thấy ở đây:

Room DB Migration Documentation

này về cơ bản làm cho DB để chạy một số SQL cung cấp tự mình cập nhật cơ sở dữ liệu lên phiên bản mới. Bằng cách này bạn có thể đảm bảo rằng không có dữ liệu nào của bạn bị mất trong khi thực hiện di chuyển; hoặc càng ít càng tốt tùy thuộc vào những gì bạn đang làm. Đây là phương pháp ưa thích cho các ứng dụng sản xuất vì nó có nghĩa là người dùng sẽ không mất dữ liệu đã tồn tại trước của họ và bạn sẽ không nhận được nhiều đánh giá tức giận/khách hàng bị mất.

Hy vọng điều đó sẽ hữu ích!

+2

Hãy nhớ thay đổi phiên bản cơ sở dữ liệu trong chú thích @Database. fallbackToDestructiveMigration() sẽ không thiết lập lại DB chỉ vì cấu trúc DB được thay đổi. – Andrew

5

Một giải pháp cho vấn đề này là xóa tệp cơ sở dữ liệu và bắt đầu lại. Đây không phải là vấn đề vì tôi chỉ đang thử nghiệm và có thể tái cơ sở dữ liệu bằng cách sử dụng dữ liệu trực tuyến.

Để làm như vậy hoặc là:

  • Thông tin ứng dụng> Bộ nhớ> Xóa dữ liệu
  • tay loại bỏ các tập tin tại /data/data/com.app.example/databases/database.db
Các vấn đề liên quan