2011-11-22 18 views
7

Tôi sử dụng Trình ContentProvider trong ứng dụng của mình và mọi thứ đều hoạt động tốt ngoại trừ một vấn đề nhỏ. Tôi có một chức năng sao lưu và phục hồi sao lưu cơ sở dữ liệu vào một tệp trên thẻ SD và sau đó các tệp sao lưu đó có thể được khôi phục để ghi đè lên cơ sở dữ liệu hiện tại. Toàn bộ quá trình này đang hoạt động, nhưng ContentProvider vẫn giữ tham chiếu/cache tới cơ sở dữ liệu gốc khi một trong các tệp sao lưu cũ được khôi phục. Tôi dường như không thể tìm cách làm mới hoặc tải lại tham chiếu cơ sở dữ liệu trong ContentProvider. Tôi biết công việc khôi phục vì tôi có thể xem các bản ghi trong db với Trình soạn thảo SQLite và khi tôi đóng và mở lại ứng dụng, nó sẽ hiển thị các bản ghi chính xác.Làm mới/Nạp lại cơ sở dữ liệu tham khảo trong ContentProvider tùy chỉnh sau khi khôi phục

Không ai biết một cách để làm điều này? Có cách nào để đóng và mở lại ContentProvider mà tôi không thấy không?

Trả lời

6

Bạn đang duy trì một tham chiếu đến thực tế SQLiteDatabase trong cung cấp nội dung của bạn (giống như gọi SQLiteOpenHelper.getWritableDatabase() trong onCreate() và sau đó giữ tham chiếu)? Hoặc bạn có nhận được đối tượng DB từ một nơi nào đó giống như một người trợ giúp trong từng phương pháp của nhà cung cấp không?

Thông thường, nếu bạn chỉ giữ một tham chiếu địa phương để các helper và nhận được có thể ghi/database instance có thể đọc được bên trong của mỗi phương pháp khi cần thiết thì vấn đề này sẽ biến mất. Nếu không, có lẽ chúng ta có thể xem mã nhà cung cấp?

Hy vọng rằng Trợ giúp!

+0

Tôi nhận được một tài liệu tham khảo từ một helper trong onCreate 'db = DbAdapter mới (getContext()); '. Đây là những gì tất cả các ví dụ hiển thị. Tôi nghĩ về việc làm nó theo từng phương pháp, nhưng điều đó có vẻ rất không hiệu quả đối với tôi và loại chậm. Bạn không nghĩ sao? Vâng, tôi đoán tôi sẽ thử nó theo cách đó và xem nó hoạt động như thế nào. Điều đó không phải là để lại một loạt các đối tượng db mở cũng như tôi có nhiều truy vấn/cập nhật hay ContentProvider sẽ quản lý chúng đúng cách? – ssuperz28

+0

Hãy xem cách các nhà cung cấp hệ thống như AlarmProvider được thực hiện như một ví dụ về những gì tôi đang nói. Nhận helper trong onCreate() và sau đó là kiểu db khi cần thiết. ContentProvider quản lý quyền truy cập yêu cầu cho bạn, đó là một trong những lý do để sử dụng nó. Đây là cách tôi xây dựng các nhà cung cấp của tôi cũng như: http://codesearch.google.com/#cZwlSNS7aEw/packages/apps/DeskClock/src/com/android/deskclock/AlarmProvider.java&exact_package=android – Devunwired

+1

Ahhh ... Tôi hiểu rồi. Tôi đang thực sự sử dụng một lớp dbadapter có chứa helper của tôi và mở db. Tôi đang di chuyển từ ứng dụng API v7 để sử dụng thư viện tương thích mới. Tôi sẽ tách người trợ giúp và thử nó theo cách này.Tôi đoán tôi chỉ không nhận ra tôi nên đã chỉ được gọi là một người trợ giúp vì vậy tôi nghĩ rằng tôi đã làm theo các ví dụ một cách chính xác. Doh! Cảm ơn! – ssuperz28

26

Nếu bạn đang nhắm mục tiêu> = API 5 bạn có thể nhận được một tham chiếu đến ContentProvider của bạn thông qua một ContentProviderClient, và chạy một phương pháp cụ thể để thực hiện của bạn:

ContentResolver resolver = context.getContentResolver(); 
ContentProviderClient client = resolver.acquireContentProviderClient("myAuthority"); 
MyContentProvider provider = (MyContentProvider) client.getLocalContentProvider(); 
provider.resetDatabase(); 
client.release(); 

Thêm phương pháp thiết lập lại để thực hiện ContentProvider của bạn:

public void resetDatabase() { 
    mDatabaseHelper.close(); 
    mDatabaseHelper = new MyDatabaseOpenHelper(context); 
} 
+0

Cảm ơn bạn về điều này. Điều này cũng rất hữu ích. Tôi phải chấp nhận câu trả lời trước đó là câu trả lời đúng mặc dù vì nó đã đẩy tôi đi đúng hướng mà không thực sự phải thay đổi nhiều. Cảm ơn! – ssuperz28

+0

'client.release();' không được chấp nhận. Sử dụng 'close()' để thay thế. –

+0

Đề cập đến điều này nếu bạn muốn xóa và tạo lại db. http://stackoverflow.com/a/42265429/1318946 –

1

đây là giải pháp của tôi.

public class DataProvider extends ContentProvider { 

    private DataDbHelper dbHelper; 

    @Override 
    public boolean onCreate() { 
     // nothing here 
     return true; 
    } 

    private DataDbHelper getDbHelper() { 
     if (dbHelper== null) { 
      // initialize 
      dbHelper = new DataDbHelper(getContext()); 
     } else if (dbHelper.getReadableDatabase().getVersion() != DataDbHelper.VERSION) { 
      // reset 
      dbHelper.close(); 
      dbHelper = new DataDbHelper(getContext()); 
     } 
     return this.mOpenHelper; 
    } 
} 

query(), insert(), update(), delete() sử dụng getDbHelper() để có được một SQLiteDatabase

Mã đầy đủ các ứng dụng Android của tôi là có sẵn here nếu bạn cần thêm thông tin.

0

Bạn cũng có thể chỉ đơn giản là sử dụng phương pháp xóa mà không có một lựa chọn:

context.getContentResolver().delete(YourProvider.CONTENT_URI, null, null); 
Các vấn đề liên quan