Działki i pakiety

Obiekty Parcelable i Bundle są przeznaczone do używania w różnych procesach, np. w transakcjach IPC/Binder, między aktywnościami za pomocą intencji oraz do przechowywania stanu tymczasowego podczas zmian konfiguracji. Na tej stronie znajdziesz zalecenia i sprawdzone metody dotyczące używania obiektów Parcelable i Bundle.

Uwaga: Parcel nie jest mechanizmem serializacji ogólnego przeznaczenia. Nie należy przechowywać danych Parcel na dysku ani wysyłać ich przez sieć.

Wysyłanie danych między aktywnościami

Gdy aplikacja tworzy obiekt Intent, aby użyć go w startActivity() do uruchomienia nowej aktywności, może przekazywać parametry za pomocą metody putExtra().

Poniższy fragment kodu pokazuje, jak wykonać tę operację.

val intent = Intent(this, MyActivity::class.java).apply {
    putExtra("media_id", "a1b2c3")
    // ...
}
startActivity(intent)

System operacyjny pakuje bazowy Bundle intencji. Następnie system operacyjny tworzy nową aktywność, rozpakowuje dane i przekazuje intencję do nowej aktywności.

Zalecamy używanie klasy Bundle do ustawiania w obiektach Intent typów prostych znanych systemowi operacyjnemu. Klasa Bundle jest wysoce zoptymalizowana pod kątem marshallingu i unmarshallingu za pomocą pakietów.

W niektórych przypadkach może być konieczne przekazywanie złożonych obiektów między aktywnościami lub zachowywanie ich w stanie interfejsu. W takich przypadkach klasa niestandardowa powinna implementować Parcelable. W przypadku nowoczesnych aplikacji w Kotlinie i Jetpack Compose zalecamy używanie adnotacji @Parcelize. Automatycznie generuje ona logikę serializacji potrzebną do bezpiecznego obsługiwania danych podczas korzystania z pakietów. Jest to ta sama metoda, która jest używana do obsługi danych podczas korzystania z rememberSaveable. Więcej informacji o używaniu @Parcelize, znajdziesz w artykule Generator implementacji Parcelable.

Podczas wysyłania danych za pomocą intencji należy ograniczyć rozmiar danych do kilku KB. Wysyłanie zbyt dużej ilości danych może spowodować, że system zgłosi wyjątek TransactionTooLargeException.

Wysyłanie danych między procesami

Wysyłanie danych między procesami jest podobne do wysyłania ich między aktywnościami. Jednak w przypadku wysyłania między procesami zalecamy, aby nie używać niestandardowych obiektów Parcelable. Jeśli wysyłasz niestandardowy obiekt Parcelable z jednej aplikacji do drugiej, musisz mieć pewność, że w obu aplikacjach jest używana dokładnie ta sama wersja klasy niestandardowej. Zwykle może to być wspólna biblioteka używana w obu aplikacjach. Jeśli aplikacja spróbuje wysłać do systemu niestandardowy obiekt Parcelable, może wystąpić błąd, ponieważ system nie może rozpakować klasy, której nie zna.

Na przykład aplikacja może ustawić alarm za pomocą klasy AlarmManager i użyć niestandardowego obiektu Parcelable w intencji alarmu. Gdy alarm się włączy, system zmodyfikuje Bundle dodatków intencji, aby dodać liczbę powtórzeń. Ta modyfikacja może spowodować, że system usunie niestandardowy obiekt Parcelable z dodatków. To usunięcie może z kolei spowodować awarię aplikacji, gdy otrzyma ona zmodyfikowaną intencję alarmu, ponieważ oczekuje dodatkowych danych, których już nie ma.

Bufor transakcji Binder ma ograniczony stały rozmiar, obecnie 1 MB, który jest współdzielony przez wszystkie transakcje w toku w procesie. Ponieważ ten limit jest na poziomie procesu, a nie na poziomie aktywności, te transakcje obejmują wszystkie transakcje Binder w aplikacji, takie jak startActivity, rememberSaveable (która używa onSaveInstanceState w tle) i wszelkie interakcje z systemem. Po przekroczeniu limitu rozmiaru zgłaszany jest wyjątek TransactionTooLargeException.

W przypadku zapisywania stanu za pomocą rememberSaveable ilość danych powinna być niewielka, ponieważ proces systemowy musi przechowywać podane dane tak długo, jak długo użytkownik może wrócić do tej aktywności (nawet jeśli proces aktywności zostanie zakończony). Zalecamy, aby zapisany stan nie przekraczał 50 KB danych.

Uwaga: w Androidzie 7.0 (poziom API 24) i nowszych wersjach system zgłasza wyjątek TransactionTooLargeException jako wyjątek środowiska wykonawczego. W starszych wersjach Androida system wyświetla tylko ostrzeżenie w Logcat.