Działki i pakiety

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.