Obiekty Parcelable
i Bundle
powinny być używane niezależnie od granic procesów, np. w transakcjach IPC/Binder, między działaniami z intencjami oraz do przechowywania stanu przejściowego w przypadku zmian konfiguracji. Na tej stronie znajdziesz rekomendacje i sprawdzone metody dotyczące używania obiektów Parcelable
i Bundle
.
Uwaga: Parcel
nie jest ogólnym mechanizmem serializacji i nie należy nigdy przechowywać żadnych danych Parcel
na dysku ani wysyłać ich przez sieć.
Przesyłanie danych między działaniami
Gdy aplikacja tworzy obiekt Intent
, który zostanie użyty w startActivity(android.content.Intent)
do uruchomienia nowej aktywności, może przekazać parametry za pomocą metody putExtra(java.lang.String, java.lang.String)
.
Poniższy fragment kodu pokazuje, jak wykonać tę operację.
Kotlin
val intent = Intent(this, MyActivity::class.java).apply { putExtra("media_id", "a1b2c3") // ... } startActivity(intent)
Java
Intent intent = new Intent(this, MyActivity.class); intent.putExtra("media_id", "a1b2c3"); // ... startActivity(intent);
System operacyjny nadaje bazowy element Bundle
intencji. Następnie system operacyjny tworzy nową aktywność, wyodrębnia dane i przekazuje intencję nowej aktywności.
Do ustawiania znanych w systemie operacyjnym obiektów podstawowych w obiektach Intent
zalecamy używanie klasy Bundle
. Klasa Bundle
jest wysoce zoptymalizowana pod kątem aranżacji i odstraszania działek.
W niektórych przypadkach może być potrzebny mechanizm do wysyłania złożonych lub złożonych obiektów między aktywnościami.
W takich przypadkach klasa niestandardowa powinna implementować interfejs Parcelable i udostępniać odpowiednią metodę writeToParcel(android.os.Parcel, int)
.
Musi też zawierać niepuste pole o nazwie CREATOR
implementujące interfejs Parcelable.Creator
, którego metoda createFromParcel()
jest używana do konwertowania obiektu Parcel
z powrotem na bieżący obiekt.
Więcej informacji znajdziesz w dokumentacji obiektu Parcelable
.
Gdy wysyłasz dane za pomocą intencji, pamiętaj, aby ograniczyć ich rozmiar do kilku kilobajtów.
Wysłanie zbyt dużej ilości danych może spowodować, że system zgłosi wyjątek TransactionTooLargeException
.
Przesyłanie danych między procesami
Przesyłanie danych między procesami przypomina proces ich przesyłania między działaniami. Jednak w przypadku wysyłania między procesami nie zalecamy używania niestandardowych paczek. Jeśli wysyłasz niestandardowy obiekt Parcelable
z jednej aplikacji do drugiej, musisz się upewnić, że ta sama wersja niestandardowej klasy jest dostępna zarówno w aplikacji wysyłającej, jak i w aplikacji odbierającej. Zwykle jest to wspólna biblioteka
używana w obu aplikacjach. Jeśli aplikacja próbuje wysłać do systemu niestandardową paczkę, może wystąpić błąd, ponieważ system nie jest w stanie cofnąć uruchomienia klasy, o której nie jest znany.
Aplikacja może na przykład ustawić alarm za pomocą klasy AlarmManager
oraz użyć niestandardowego Parcelable
w intencji alarmu. Po uruchomieniu alarmu system zmienia Bundle
dodatków intencji, aby dodać liczbę powtórzeń. Ta modyfikacja może spowodować, że system usunie niestandardowy Parcelable
z dodatkowych. Takie usunięcie może z kolei spowodować awarię aplikacji po otrzymaniu zmodyfikowanej intencji alarmu, ponieważ oczekuje ona otrzymania dodatkowych danych, których już nie ma.
Bufor transakcji Binder ma ograniczony stały rozmiar (obecnie 1 MB), który jest wspólny dla wszystkich transakcji w toku. Ponieważ limit ten jest na poziomie procesu, a nie na poziomie działania, transakcje te obejmują wszystkie transakcje powiązane w aplikacji, np. onSaveInstanceState, startActivity i wszelkie interakcje z systemem. Po przekroczeniu limitu rozmiaru zgłaszany jest wyjątek TransactionTooLargeWyjątek.
W szczególności z zapisanym stanem instancji dane należy przesyłać niewielką ilość danych, ponieważ proces systemowy musi przechowywać przekazywane dane tak długo, jak użytkownik może do nich wrócić (nawet jeśli proces aktywności zostanie przerwany). Zalecamy ustawienie wartości poniżej 50 tys.
Uwaga: w Androidzie 7.0 (poziom interfejsu API 24) i nowszych system zgłasza wyjątek TransactionTooLargeWyjątek jako wyjątek w czasie działania. W starszych wersjach Androida system wyświetla ostrzeżenie tylko w logcat.