2011-11-22 7 views
7

Używam ContentProvider w mojej aplikacji i wszystko działa świetnie, z wyjątkiem jednego małego problemu. Mam funkcję kopii zapasowej i przywracania, która tworzy kopię zapasową bazy danych do pliku na karcie SD, a następnie te pliki kopii zapasowych można przywrócić, aby nadpisać bieżącą bazę danych. Cały ten proces działa, ale ContentProvider nadal przechowuje referencje/cache do oryginalnej bazy danych po przywróceniu jednego ze starych plików kopii zapasowej. Nie mogę znaleźć sposobu na odświeżenie lub ponowne załadowanie odwołania do bazy danych w ContentProvider. Wiem, że przywracanie działa, ponieważ widzę rekordy w db z edytorem SQLite i kiedy zamykam i ponownie otwieram aplikację, wyświetla ona poprawne rekordy.Odśwież/wczytaj odniesienie do bazy danych w niestandardowym narzędziu ContentProvider po odtworzeniu.

Czy ktoś wie, jak to zrobić? Czy istnieje sposób zamknięcia i ponownego otwarcia ContentProvider, którego nie widzę?

Odpowiedz

6

Czy zachowujesz odniesienie do faktycznego SQLiteDatabase w swoim dostawcy treści (np. Dzwoniąc pod numer SQLiteOpenHelper.getWritableDatabase() w onCreate(), a następnie zachowując to odwołanie)? Lub możesz uzyskać obiekt DB z dowolnego miejsca jak pomocnika w każdej metody dostawcy?

Zwykle, jeśli przechowujesz lokalne odniesienie do helpera i otrzymujesz zapisywalną/czytelną instancję bazy danych wewnątrz każdej metody, wtedy ten problem powinien zniknąć. Jeśli nie, być może możemy rzucić okiem na kod dostawcy?

Nadzieję, że pomaga!

+0

jestem coraz odwołanie od pomocnika w onCreate 'db = new dbAdapter (getContext());'. Oto, co pokazują wszystkie przykłady. Myślałem o zrobieniu tego w każdej z metod, ale wydaje mi się to bardzo nieefektywne i powolne. Nie sądzisz? Cóż, myślę, że spróbuję w ten sposób i zobaczę jak to działa. Czy to nie pozostawi zbyt wielu otwartych obiektów db, jeśli mam wiele zapytań/aktualizacji lub czy ContentProvider będzie je odpowiednio zarządzać? – ssuperz28

+0

Zobacz, jak dostawcy systemu, jak np. AlarmProvider, robią przykład tego, co mówię. Uzyskiwanie pomocnika onCreate(), a następnie, w razie potrzeby, typu db. ContentProvider zarządza dostępem do żądania, jest to jeden z powodów, aby z niego skorzystać. Tak właśnie buduję swoich dostawców: http://codesearch.google.com/#cZwlSNS7aEw/packages/apps/DeskClock/src/com/android/deskclock/AlarmProvider.java&exact_package=android – Devunwired

+1

Ahhh ... Rozumiem. Właściwie używam klasy dbadapter, która mieści mojego pomocnika i otwiera bazę danych. Przeprowadzam migrację z aplikacji API v7, aby użyć nowej biblioteki zgodności. Oddzielę pomocnika i spróbuję w ten sposób.Chyba po prostu nie zdawałem sobie sprawy, że powinienem był dzwonić do pomocnika, więc pomyślałem, że poprawnie stosuję się do przykładów. Doh! Dzięki! – ssuperz28

26

Jeśli są kierowane> = API 5 można uzyskać odniesienie do swojej ContentProvider pośrednictwem ContentProviderClient i uruchom sposób specyficzny do realizacji:

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

dodać metodę resetowania do realizacji ContentProvider:

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

Dziękuję za to również. Jest to również bardzo przydatne. Muszę zaakceptować poprzednią odpowiedź jako poprawną odpowiedź, ponieważ popchnęła mnie we właściwym kierunku, nie musiąc wiele zmieniać. Dzięki! – ssuperz28

+0

'client.release();' jest przestarzałe. Zamiast tego użyj 'close()'. –

+0

Skorzystaj z tego, jeśli chcesz usunąć i ponownie utworzyć bazę danych. http://stackoverflow.com/a/42265429/1318946 –

1

Oto moje rozwiązanie.

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() użycie getDbHelper() celu uzyskania SQLiteDatabase

pełny kod mojego Android aplikacji jest dostępny here jeśli potrzebujesz więcej informacji.

0

Można też po prostu użyć metody usuwania bez wyboru:

context.getContentResolver().delete(YourProvider.CONTENT_URI, null, null); 
Powiązane problemy