Wraz z wydaniem Gingerbread eksperymentowałem z niektórymi nowymi API, z których jeden to StrictMode .
Zauważyłem, że jedno z ostrzeżeń dotyczy getSharedPreferences()
.
To jest ostrzeżenie:
StrictMode policy violation; ~duration=1949 ms: android.os.StrictMode$StrictModeDiskReadViolation: policy=23 violation=2
i jest podawany dla getSharedPreferences()
wywołania w wątku interfejsu użytkownika.
Czy SharedPreferences
dostęp i zmiany naprawdę powinny być dokonywane poza wątkiem interfejsu użytkownika?
android
sharedpreferences
android-strictmode
cottonBallPaws
źródło
źródło
Odpowiedzi:
Cieszę się, że już się tym bawisz!
Kilka uwag: (w leniwej formie punktora)
Ale jeśli chodzi o ładowanie ...
po załadowaniu SharedPreferences są pojedyncze i buforowane w całym procesie. więc chcesz załadować go jak najwcześniej, aby mieć go w pamięci, zanim będzie potrzebny. (zakładając, że jest mały, tak jak powinien być, jeśli używasz SharedPreferences, prostego pliku XML ...) Nie chcesz w przyszłości nic zarzucić, gdy jakiś użytkownik kliknie przycisk.
ale za każdym razem, gdy wywołujesz context.getSharedPreferences (...), zapasowy plik XML jest statystycznie sprawdzany, czy został zmieniony, więc i tak będziesz chciał uniknąć tych statystyk podczas zdarzeń interfejsu użytkownika. Statystyka powinna być normalnie szybka (i często zapisywana w pamięci podręcznej), ale yaffy nie mają zbyt wiele na drodze współbieżności (a wiele urządzeń z Androidem działa na yaffach ... Droid, Nexus One itp.), Więc jeśli unikniesz dysku , unikniesz utknięcia za innymi operacjami w locie lub oczekującymi na dysku.
więc prawdopodobnie będziesz chciał załadować SharedPreferences podczas onCreate () i ponownie użyć tej samej instancji, unikając statystyki.
ale jeśli i tak nie potrzebujesz swoich preferencji podczas onCreate (), ten czas ładowania niepotrzebnie opóźnia uruchomienie aplikacji, więc generalnie lepiej jest mieć coś w rodzaju podklasy FutureTask <SharedPreferences>, która uruchamia nowy wątek do .set. () wartość podklas FutureTask. Następnie po prostu wyszukaj członka swojego FutureTask <SharedPreferences>, kiedy tylko tego potrzebujesz i .get () go. Planuję udostępnić to za kulisami w Honeycomb, w sposób przejrzysty. Spróbuję opublikować przykładowy kod, który pokazuje najlepsze praktyki w tej dziedzinie.
Sprawdź blog programistów Androida, aby zobaczyć nadchodzące posty na tematy związane ze StrictMode w nadchodzących tygodniach.
źródło
Dostęp do wspólnych preferencji może zająć trochę czasu, ponieważ są one odczytywane z pamięci flash. Czy dużo czytasz? Może mógłbyś wtedy użyć innego formatu, np. Bazy danych SQLite.
Ale nie naprawiaj wszystkiego, co znajdziesz, używając StrictMode. Lub zacytować dokumentację:
źródło
Jedna subtelność w odpowiedzi Brada: nawet jeśli załadujesz SharedPreferences w onCreate (), prawdopodobnie nadal powinieneś czytać wartości w wątku w tle, ponieważ getString () itp. Blokuje się do momentu odczytania preferencji udostępnionego pliku w zakończeniach (w wątku w tle):
edit () również blokuje w ten sam sposób, chociaż apply () wydaje się być bezpieczny w wątku pierwszego planu.
(Swoją drogą, przepraszam, że to tutaj zapisuję. Umieściłbym to jako komentarz do odpowiedzi Brada, ale właśnie dołączyłem i nie mam wystarczającej reputacji, aby to zrobić.)
źródło
Wiem, że to stare pytanie, ale chcę się podzielić moim podejściem. Miałem długi czas czytania i korzystałem z kombinacji wspólnych preferencji i globalnej klasy aplikacji:
Klasa aplikacji:
LocalPreference:
MainActivity (aktywność, która jest wywoływana jako pierwsza w aplikacji):
Kroki wyjaśnione:
UWAGA: ZAWSZE sprawdzaj, czy zmienna dotycząca całej aplikacji różni się od NULL, powód -> http://www.developerphil.com/dont-store-data-in-the-application-object/
Gdybym nie sprawdzał na null, pozwoliłbym na wyrzucenie nullpointer podczas wywoływania na przykład getMaxDistance () na obiekcie filtru (jeśli obiekt aplikacji został usunięty z pamięci przez Androida)
źródło
Klasa SharedPreferences wykonuje pewne odczyty i zapisy w plikach XML na dysku, więc podobnie jak każda inna operacja we / wy może blokować. Ilość danych aktualnie przechowywanych w SharedPreferences wpływa na czas i zasoby zużywane przez wywołania interfejsu API. W przypadku minimalnych ilości danych pobranie / umieszczenie danych zajmuje kilka milisekund (czasami nawet mniej niż milisekundę). Jednak z punktu widzenia eksperta może być ważne, aby poprawić wydajność, wykonując wywołania API w tle. W przypadku asynchronicznych SharedPreferences sugeruję sprawdzenie biblioteki Datum .
źródło