Muszę przekazać odwołanie do klasy, która wykonuje większość mojego przetwarzania, za pośrednictwem pakietu.
Problem polega na tym, że nie ma to nic wspólnego z intencjami ani kontekstami i zawiera dużą liczbę nieprymitywnych obiektów. Jak spakować klasę do pliku parcelable / serializowalnego i przekazać go do pliku startActivityForResult
?
Odpowiedzi:
Zastanowienie się, jaką ścieżkę obrać, wymaga odpowiedzi nie tylko na kluczowe pytanie CommonsWare „dlaczego”, ale także na pytanie „do czego?” zdajesz to.
W rzeczywistości jedyną rzeczą, która może przejść przez pakiety, są zwykłe dane - wszystko inne opiera się na interpretacjach tego, co te dane oznaczają lub na co wskazują. Nie możesz dosłownie przekazać obiektu, ale możesz zrobić jedną z trzech rzeczy:
1) Możesz rozbić obiekt na dane składowe, a jeśli to, co znajduje się po drugiej stronie, ma wiedzę o tym samym rodzaju obiektu, może złożyć klon z serializowanych danych. W ten sposób większość typowych typów przechodzi przez pakiety.
2) Możesz przejść przez nieprzezroczysty uchwyt. Jeśli przekazujesz go w tym samym kontekście (choć można by zapytać, po co się przejmować), będzie to uchwyt, który możesz wywołać lub wyłuskać. Ale jeśli przekażesz go przez Binder do innego kontekstu, jego wartość literalna będzie dowolną liczbą (w rzeczywistości te arbitralne liczby liczą się sekwencyjnie od uruchomienia). Nie możesz nic zrobić, ale śledzić to, dopóki nie przekażesz go z powrotem do oryginalnego kontekstu, co spowoduje, że Binder przekształci go z powrotem w oryginalny uchwyt, czyniąc go ponownie użytecznym.
3) Możesz przekazać magiczny uchwyt, taki jak deskryptor pliku lub odniesienie do pewnych obiektów systemu operacyjnego / platformy, a jeśli ustawisz odpowiednie flagi, Binder utworzy klon wskazujący na ten sam zasób dla odbiorcy, który może być faktycznie użyty na Drugi koniec. Ale działa to tylko w przypadku kilku typów obiektów.
Najprawdopodobniej albo przekazujesz swoją klasę tylko po to, aby drugi koniec mógł ją śledzić i zwrócić ci później, albo przekazujesz ją do kontekstu, w którym można utworzyć klon z serializowanych danych składowych ... albo też próbujesz zrobić coś, co po prostu nie zadziała i musisz przemyśleć całe podejście.
źródło
Możesz także użyć Gson, aby przekonwertować obiekt na JSONObject i przekazać go w pakiecie. Dla mnie był to najbardziej elegancki sposób, w jaki to zrobiłem. Nie testowałem, jak to wpływa na wydajność.
W początkowej działalności
W następnej czynności
źródło
Parcelable interfejs jest dobrym sposobem, aby przekazać obiekt z zamiarem.
Jak mogę nadać przesyłkę moich niestandardowych obiektów? to całkiem dobra odpowiedź na temat korzystania z Parcelable
Oficjalne dokumenty Google zawierają również przykład
źródło
Możesz użyć globalnego stanu aplikacji .
Aktualizacja:
Dostosuj, a następnie dodaj to do swojego pliku AndroidManifest.xml:
A potem miej w swoim projekcie zajęcia takie jak ta:
A ponieważ „ Dostęp do niego można uzyskać przez getApplication () z dowolnego działania lub usługi ”, używasz go w następujący sposób:
Mam nadzieję, że to pomoże.
źródło
Możesz także uczynić swoje obiekty Serializowalnymi i użyć metod getSerializable i putSerializable pakietu .
źródło
Możliwe rozwiązanie:
Klasa CustomObject:
Obiekty podrzędne:
źródło
Jeszcze jednym sposobem wysyłania obiektów za pośrednictwem pakietu jest użycie
bundle.putByteArray
przykładowego kodu
umieść Object of DataBean w Bundle:
Konwersja obiektów na tablice bajtowe
Odzyskaj obiekt z paczki:
Metoda pobierania obiektów z tablic bajtowych:
Mam nadzieję, że to pomoże innym kumplom.
źródło
1.Bardzo bezpośredni i łatwy w użyciu przykład, uczynienie obiektu, który ma zostać przekazany, implementuje możliwość serializacji.
2. przekazać obiekt w pakiecie
3. get przekazany obiekt z pakietu jako Serializable, a następnie rzut do Object.
źródło
To bardzo spóźniona odpowiedź na moje własne pytanie, ale wciąż przykuwa uwagę, więc czuję, że muszę się nim zająć. Większość z tych odpowiedzi jest poprawna i doskonale radzi sobie z pracą. Zależy to jednak od potrzeb aplikacji. Ta odpowiedź posłuży do opisania dwóch rozwiązań tego problemu.
Podanie
Pierwszą z nich jest Aplikacja , ponieważ najczęściej mówiono o niej tutaj. Aplikacja jest dobrym obiektem do umieszczania jednostek, które wymagają odwołania do kontekstu. `ServerSocket` niewątpliwie potrzebowałby kontekstu (dla wejścia / wyjścia pliku lub prostych aktualizacji elementu ListAdapter). Ja osobiście wolę tę trasę. Lubię aplikacje, są przydatne do pobierania kontekstu (ponieważ mogą być statyczne i prawdopodobnie nie powodują wycieku pamięci) i mają prosty cykl życia.Usługa
Service` jest drugi. „Usługa” jest właściwie lepszym wyborem dla mojego problemu, ponieważ do tego właśnie służą usługi: Usługi są schludne, ponieważ mają bardziej zdefiniowany cykl życia, który jest łatwiejszy do kontrolowania. Ponadto, w razie potrzeby, usługi mogą działać poza aplikacją (tj. Podczas rozruchu). Może to być konieczne w przypadku niektórych aplikacji lub po prostu fajnej funkcji.Nie był to pełny opis, ale zostawiłem linki do dokumentów dla tych, którzy chcą dokładniej zbadać sprawę. Ogólnie rzecz biorąc,
Service
jest to lepsze dla instancji, której potrzebowałem - uruchamiając ServerSocket na moim urządzeniu SPP.źródło
Natknąłem się na to pytanie, kiedy szukałem sposobu na przekazanie obiektu Date. W moim przypadku, jak sugerowano w odpowiedziach, użyłem Bundle.putSerializable (), ale to nie zadziałałoby w przypadku tak złożonej rzeczy, jak opisany DataManager w oryginalnym poście.
Moja sugestia, która da bardzo podobny rezultat do umieszczenia wspomnianego DataManagera w Aplikacji lub uczynienia go Singletonem, to użycie Dependency Injection i powiązanie DataManagera z zakresem Singleton i wstrzyknięcie DataManagera tam, gdzie jest to potrzebne. Zyskasz nie tylko korzyść w postaci zwiększonej testowalności, ale także uzyskasz czystszy kod bez całego kotłowego kodu „przekazywania zależności między klasami i działaniami”. (Robo) Guice jest bardzo łatwy w obsłudze, a nowy framework Dagger również wygląda obiecująco.
źródło
inny prosty sposób na przekazanie obiektu za pomocą pakietu:
źródło