2009-10-12 31 views
16

Có thể hai hoặc nhiều Hoạt động trên Android mở cơ sở dữ liệu sqlite3 để viết không?Chia sẻ cơ sở dữ liệu sqlite giữa nhiều Hoạt động Android

Tôi có hai Hoạt động cần chèn dữ liệu vào cùng cơ sở dữ liệu sqlite. Khi Hoạt động thứ hai gọi SQLiteOpenHelper.getWriteableDatabase() một ngoại lệ IllegalStateException được ném với thông báo "SQLiteDatabase được tạo và không bao giờ đóng".

Tôi đã có thể tránh ngoại lệ bằng cách làm cho đối tượng cơ sở dữ liệu của tôi trở thành một singleton nhưng tôi nghĩ rằng phải có cách tốt hơn.

Cảm ơn,

John

+0

Bạn có thể đóng db sau khi bạn đã viết cho nó .. – svens

+0

Tôi cũng nghĩ về điều đó, nhưng một hoạt động là ListActivity được điền bằng bộ điều hợp con trỏ. Tôi nghĩ rằng đóng cơ sở dữ liệu sẽ làm cho requery của bộ điều hợp thất bại. –

+0

@John: nếu bạn sử dụng cơ sở dữ liệu singleton, bạn mở và đóng nó ở đâu? – Emerald214

Trả lời

14

Có bao giờ thực sự nhiều hơn một Hoạt động chạy cùng một lúc. Cách dễ dàng để khắc phục điều này là để Hoạt động đầu tiên đóng kết nối trước khi bắt đầu Hoạt động thứ hai. Bạn có thể làm điều này trong onPause() sau đó mở lại nó trong onResume(). Một cái gì đó như thế này (rất psuedo-code):

MyActivity { 
    OnResume() 
     open connection to database 
    OnPause() 
     close connection to database 
} 

Bằng cách này bạn sẽ không bao giờ cố gắng để có nhiều hơn một kết nối tại một thời điểm và kết nối luôn luôn có sẵn.

+3

Tôi đã tự hỏi nếu cách tiếp cận này là tốt hơn so với việc có các hoạt động sử dụng cùng một đối tượng singleton.Tôi nghĩ đó là vì cách tiếp cận này để lại kết nối là trạng thái đúng khi tạm dừng một hoạt động. Có một kết nối singleton làm cho vấn đề dọn dẹp. Cảm ơn. –

+0

Vâng ... nếu bạn không đóng nó trong onPause thì kết nối chỉ được để lại ở đó có treo lơ lửng nếu (ví dụ) bạn nhận được một cuộc gọi điện thoại. –

+0

Điều này không hoạt động. Tôi nhận được một InvalidStateException và một truy vấn SQL mà không thực hiện được, ngay cả trước khi onResume() được gọi. Android dường như là con trỏ requerying trước khi gọi onResume(). – cdonner

2

Tôi cũng có nhiều Hoạt động và mỗi Hoạt động sẽ mở kết nối cơ sở dữ liệu của riêng mình. Tôi giữ cho hoạt động chính còn sống trong khi tôi bắt đầu các hoạt động khác, và tôi gọi kết thúc() về các hoạt động của trẻ khi tôi không còn cần chúng nữa.

Điều tôi thấy là một đứa trẻ Hoạt động có thể mở thành công dữ liệu kết nối và truy vấn trong khi Actitity chính vẫn đang giữ trên DBAdapter của nó. Khi Activity con kết thúc, Activity chính sẽ yêu cầu bất kỳ con trỏ nào đang mở. Điều này dường như xảy ra tự động.

Tuy nhiên, sau khi nhấp vào xung quanh trên giao diện người dùng trong một thời gian, gây ra ứng dụng của tôi để bắt đầu và kết thúc hoạt động, tôi cuối cùng sẽ có được ngoại lệ:

ERROR/Database(17657): Leak found 
ERROR/Database(17657): java.lang.IllegalStateException: 
     /data/data/yourpackage/databases/yourdatabase 
     SQLiteDatabase created and never closed 
ERROR/Database(17657): at android.database.sqlite.SQLiteDatabase.<init> 
    (SQLiteDatabase.java:1694) 

Trường hợp ngoại lệ không phải là từ Hoạt động đó là hiện tại ở tiền cảnh, nhưng từ một trong đó đã được hoàn thành một thời gian trước đây. Vì vậy, điều xảy ra là bộ thu gom rác đang dọn dẹp và tìm kết nối cơ sở dữ liệu mở. Điều này không ảnh hưởng đến ứng dụng - nó tiếp tục hoạt động tốt và tất cả các truy vấn từ dữ liệu trả về Hoạt động nền trước.

Giải pháp đơn giản là đóng kết nối trong Hoạt động con. Sự kiện onDestroy() là nơi thích hợp để làm điều đó:

@Override  
protected void onDestroy() {   
    super.onDestroy(); 
    myAdapter.close(); 
} 

Vì tôi đặt điều này trong tất cả các hoạt động của con tôi, tôi không còn bị ngoại lệ.

0

Điều tôi sẽ làm là xác định cơ sở dữ liệu trong một siêu lớp là AppCompatActivity nếu tất cả các hoạt động mở rộng lớp này hoặc xác định nó trong lớp Hoạt động được kế thừa cho tất cả các hoạt động.

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