Jeśli tylko przepuszczasz przedmioty, to Parcelable został do tego zaprojektowany. Wymaga nieco więcej wysiłku, niż użycie natywnej serializacji Javy, ale jest o wiele szybszy (i mam na myśli sposób, WAY szybszy).
Z dokumentacji prosty przykład implementacji to:
// simple class that just has one member property as an examplepublicclassMyParcelableimplementsParcelable{privateint mData;/* everything below here is for implementing Parcelable */// 99.9% of the time you can just ignore this@Overridepublicint describeContents(){return0;}// write your object's data to the passed-in Parcel@Overridepublicvoid writeToParcel(Parcelout,int flags){out.writeInt(mData);}// this is used to regenerate your object. All Parcelables must have a CREATOR that implements these two methodspublicstaticfinalParcelable.Creator<MyParcelable> CREATOR =newParcelable.Creator<MyParcelable>(){publicMyParcelable createFromParcel(Parcelin){returnnewMyParcelable(in);}publicMyParcelable[] newArray(int size){returnnewMyParcelable[size];}};// example constructor that takes a Parcel and gives you an object populated with it's valuesprivateMyParcelable(Parcelin){
mData =in.readInt();}}
Zauważ, że w przypadku, gdy masz więcej niż jedno pole do pobrania z danej paczki, musisz to zrobić w tej samej kolejności, w jakiej je umieściłeś (czyli w podejściu FIFO).
Gdy masz swoje obiekty realizować Parcelableto tylko kwestia oddania ich do swoich zamiarów z putExtra () :
Intent i =newIntent();
i.putExtra("name_of_extra", myParcelableObject);
Jak można to zrealizować, gdy mData jest obiektem (np. JSONObject), a nie intem?
Peter Ajtai,
301
Dlaczego nie można po prostu przejść obok obiektu bez tego wszystkiego? Chcemy przekazać obiekt, który jest już w pamięci.
ceklock
110
@tecnotron, ponieważ jego aplikacje są w różnych procesach i mają osobne przestrzenie adresowe pamięci, nie można po prostu wysłać wskaźnika (odwołania) do bloku pamięci w procesie i oczekiwać, że będzie on dostępny w innym procesie.
marcinj
12
Co mam zrobić, jeśli nie mogę uczynić klasy obiektu możliwą do serializacji lub parceable?
Amel Jose
11
@ceklock powód tego jest następujący: Gdy aktywność jest opóźniona, a następnie zabita z pamięci, a następnie, gdy użytkownik otworzy ją z menu ostatnich, musi utworzyć Aktywność tam, gdzie została przerwana. Musi to być ten sam interfejs użytkownika. W tym przypadku obiekt nie znajduje się w pamięci. Ale intencją jest.
tasomaniac
194
Musisz serializować swój obiekt do pewnego rodzaju reprezentacji ciągu. Jedną z możliwych reprezentacji ciągów jest JSON, a jednym z najprostszych sposobów serializacji do / z JSON w Androidzie , jeśli mnie pytasz, jest Google GSON .
W takim przypadku po prostu wstawisz wartość zwracaną z ciągu (new Gson()).toJson(myObject);i pobierzesz wartość ciągu, a następnie użyjesz go, fromJsonaby z powrotem przekształcić go w obiekt.
Jeśli twój obiekt nie jest zbyt skomplikowany, może nie być warty narzutu i zamiast tego możesz rozważyć przekazanie oddzielnych wartości obiektu.
Zgaduję, ponieważ odpowiedź fiXedd rozwiązuje ten sam problem bez korzystania z bibliotek zewnętrznych, w sposób, który jest po prostu tak bardzo preferowany, że nikt nigdy nie powinien mieć powodu, aby przejść przez zaproponowane przeze mnie rozwiązanie (nieświadome w tym czasie genialne rozwiązanie fiXedd)
David Hedlund,
5
Myślę, że to prawda. Ponadto JSON jest protokołem bardziej odpowiednim dla klienta / serwera, a nie między wątkami.
mobibob
16
Niekoniecznie zły pomysł, zwłaszcza. ponieważ Gson jest znacznie prostszy w użyciu niż implementacja paczkowania dla wszystkich obiektów, które chcesz wysłać.
uvesten
7
ponieważ używam gson w mojej aplikacji, jest to naprawdę łatwy i przyjemny sposób!
Lars,
16
String s = (new Gson().toJson(client));Cli client = new Gson().fromJson(s, Cli.class);
Dobra
155
Możesz wysłać obiekt możliwy do serializacji poprzez zamiar
// send where details is objectClassName details =newClassName();Intent i =newIntent(context,EditActivity.class);
i.putExtra("Editing", details);
startActivity(i);//receiveClassName model =(ClassName) getIntent().getSerializableExtra("Editing");AndClassClassNameimplementsSerializable{}
co jeśli działanie jest już uruchomione, czy należy wykonać startActivity (i); ? Mam na myśli, czy mogę wykonać działanie A wywołać działanie B , a to zwróci dane do działania A ? jestem zdezorientowany?
Francisco Corrales Morales
3
@ Wydajność Seraphima ma znaczenie, jeśli szeregujesz wiele obiektów, ale użytkownik nie zauważy, że szeregowanie jednego obiektu zajmuje 1 ms lub 10 ms. Jeśli celowy dodatek jest już, Serializableale nie Parcelablejest, rzadko warto się nim męczyć Parcelable.
Kevin Krumwiede
67
W sytuacjach, w których wiesz, że będziesz przekazywać dane w aplikacji, użyj „globałów” (takich jak klasy statyczne)
Oto, co Dianne Hackborn (hackbod - inżynier oprogramowania Google na Androida) powiedział w tej sprawie:
W sytuacjach, gdy wiesz, że działania przebiegają w tym samym procesie, możesz po prostu udostępniać dane za pośrednictwem globali. Na przykład możesz mieć globalny, HashMap<String, WeakReference<MyInterpreterState>>
a kiedy tworzysz nowy MyInterpreterState, wymyślisz dla niego unikalną nazwę i umieścisz go na mapie hash; aby wysłać ten stan do innego działania, wystarczy umieścić unikatową nazwę na mapie skrótu, a po uruchomieniu drugiego działania może on pobrać MyInterpreterState z mapy skrótu o nazwie, którą otrzymuje.
tak, wydawało mi się dziwne, że dostaliśmy te zamiary do wykorzystania, a następnie najlepszy inżynier mówi nam, abyśmy po prostu używali globałów do naszych danych. Ale tam jest prosto z ust koni.
Richard Le Mesurier
1
Czy słabe referencje nie byłyby tutaj ofiarą wywozu śmieci?
uLYsseus
1
@ uLYsseus sądzi, że taki jest pomysł, kiedy skończysz z nimi w działaniach ... więc gdy odpowiednie działania zostaną zniszczone, pozwoli to gc
Peter Ajtai
1
@RichardLeMesurier Myślałem o tym samym, ale potem spojrzałem na wyżej wspomniany post Grup dyskusyjnych Google od Dianne Hackborn, a ona wspomina, że naprawdę jedynym problemem z globalsami byłby przy użyciu ukrytych zamiarów (które mogą uruchomić działanie poza pakietem ). Ma to sens, jak wspomina Dianne, ponieważ te działania najprawdopodobniej nie miałyby wiedzy o typach niestandardowych, które im przekazujesz. Kiedy to przeczytałem, stało się dla mnie jasne, dlaczego globały mogą nie być tak złą drogą w tych okolicznościach, i pomyślałem, że podzielę się, na wypadek, gdyby inni też byli ciekawi
BMB
intencje zostały przerobione do tego stopnia, że można je było przenieść na inny komputer. co oczywiście nie jest dobrym sposobem na zrobienie czegokolwiek, gdy faktycznie masz tylko jeden proces, w którym się mnożysz. powody, dla których nie jest to dobre: użycie pamięci, użycie procesora, użycie baterii. ten ostatni szczególnie dokonywał wyborów projektowych z intencjami dość kłopotliwymi z perspektywy czasu. są ludzie, którzy twierdzą, że to dobry pomysł, zwykle dlatego, że „tak powiedział Google”.
Lassi Kinnunen
49
Twoja klasa powinna implementować Serializable lub Parcelable.
Twoja klasa musi zaimplementować Serializablejest niewłaściwa. Klasa może Parcelablena przykład zaimplementować .
Marc Plano-Lesay
Jakie są różnice między Paczkowanym a Serializable @Kernald? pod względem czasu przetwarzania jest to wolniejsze / nie jest to najlepsza praktyka czy coś takiego?
gumuruh
Chociaż Serializablejest standardowym interfejsem Java, Parcelablejest specyficzny dla Androida. Pod względem wydajności Parcelable jest bardziej wydajny: developerphil.com/parcelable-vs-serializable
Marc Plano-Lesay
35
Krótka odpowiedź na szybką potrzebę
1. Zaimplementuj swoją klasę do postaci szeregowej.
Jeśli masz jakieś wewnętrzne klasy, nie zapomnij o ich wdrożeniu w Serializable !!
To samo możesz osiągnąć, implementując interfejs Parcelable. Interfejs paczkowany wymaga więcej czasu na wdrożenie niż Serializable ze względu na rozmiar kodu. Ale działa szybciej niż Serializable i zużywa mniej zasobów.
Kwnstantinos Nikoloutsos
27
jeśli twoja klasa obiektów implementuje Serializable, nie musisz nic więcej robić, możesz przekazać obiekt możliwy do serializacji. tego używam.
Istnieje kilka sposobów uzyskiwania dostępu do zmiennych lub obiektów w innych klasach lub działaniu.
A. Baza danych
B. wspólne preferencje.
C. Serializacja obiektów.
D. Klasa, która może przechowywać wspólne dane, może zostać nazwana jako Common Utilities, zależna od Ciebie.
E. Przekazywanie danych przez intencje i interfejs paczkowany.
To zależy od potrzeb twojego projektu.
A. Baza danych
SQLite to baza danych Open Source, która jest wbudowana w system Android. SQLite obsługuje standardowe funkcje relacyjnej bazy danych, takie jak składnia SQL, transakcje i przygotowane wyciągi.
Załóżmy, że chcesz zapisać nazwę użytkownika. Tak więc będą teraz dwie rzeczy: kluczowa nazwa użytkownika, wartość wartości.
Jak przechowywać
// Create object of SharedPreferences.SharedPreferences sharedPref =PreferenceManager.getDefaultSharedPreferences(this);//now get EditorSharedPreferences.Editor editor = sharedPref.edit();//put your value
editor.putString("userName","stackoverlow");//commits your edits
editor.commit();
Serlizacja obiektów jest stosowana, jeśli chcemy zapisać stan obiektu, aby wysłać go przez sieć lub można go również użyć do własnych celów.
Używaj fasoli java i przechowuj w niej jako jedno z jego pól i używaj do tego getters i setter
JavaBeans to klasy Java, które mają właściwości. Traktuj właściwości jako zmienne instancji prywatnej. Ponieważ są prywatne, jedynym sposobem, aby uzyskać do nich dostęp spoza ich klasy, są metody w klasie. Metody zmieniające wartość właściwości nazywane są metodami ustawiającymi, a metody pobierające wartość właściwości nazywane są metodami pobierającymi.
Następnie użyj obiektu Serialzation, aby serializować ten obiekt, a w drugiej klasie deserializować ten obiekt.
W serializacji obiekt może być reprezentowany jako ciąg bajtów, który zawiera dane obiektu, a także informacje o typie obiektu i typach danych przechowywanych w obiekcie.
Po zapisaniu serializowanego obiektu w pliku można go odczytać z pliku i dokonać deserializacji, to znaczy informacje o typie i bajty reprezentujące obiekt oraz jego dane można wykorzystać do odtworzenia obiektu w pamięci.
Jeśli chcesz samouczek do tego, skorzystaj z tego linku
Preferowane do bezpośredniej realizacji paczkowej, IMHO. Pakiet sam w sobie implementuje opcję paczkowania, dzięki czemu zyskujesz na wydajności, unikając przy tym wszystkich problemów z jej implementacją. Zamiast tego możesz użyć par klucz-wartość do przechowywania i pobierania danych, które są znacznie bardziej niezawodne niż poleganie na zwykłej kolejności.
Risadinha
Paczkowanie wydaje mi się skomplikowane, w powyższej odpowiedzi używam metody toBundle z klasy na jego obiekcie, więc obiekt jest konwertowany na pakiet, a następnie możemy użyć konstruktora do konwersji pakietu na obiekt klasy.
om252345
To rozwiązanie jest wykonalne tylko wtedy, gdy przekazujesz pojedynczy obiekt przez zamiar.
TheIT
Jak json, ale myślę, że json jest lekki.
David
Czy obiekt, gdy go odzyskam, będzie tym samym obiektem lub kopią?
Markus
15
Dzięki za przesyłkę, ale znalazłem jeszcze jedno opcjonalne rozwiązanie
dobra odpowiedź, ale podnieś swoje standardy kodowania ... +1 za wprowadzenie Serializowalnego w konkursie, jednak paczki są znacznie szybsze ...
Amit
13
Używam Gsona z jego tak potężnym i prostym interfejsem API, aby przesyłać obiekty między czynnościami,
Przykład
// This is the object to be sent, can be any objectpublicclassAndroidPacket{publicStringCustomerName;//constructorpublicAndroidPacket(String cName){CustomerName= cName;}// other fields ....// You can add those functions as LiveTemplate !publicString toJson(){Gson gson =newGson();return gson.toJson(this);}publicstaticAndroidPacket fromJson(String json){Gson gson =newGson();return gson.fromJson(json,AndroidPacket.class);}}
2 funkcje dodajesz je do obiektów, które chcesz wysłać
Stosowanie
Wyślij obiekt od A do B.
// Convert the object to string using GsonAndroidPacket androidPacket =newAndroidPacket("Ahmad");String objAsJson = androidPacket.toJson();Intent intent =newIntent(A.this, B.class);
intent.putExtra("my_obj", objAsJson);
startActivity(intent);
Odbierz w B
@Overrideprotectedvoid onCreate(Bundle savedInstanceState){Bundle bundle = getIntent().getExtras();String objAsJson = bundle.getString("my_obj");AndroidPacket androidPacket =AndroidPacket.fromJson(objAsJson);// Here you can use your ObjectLog.d("Gson", androidPacket.CustomerName);}
Używam go prawie w każdym projekcie i nie mam problemów z wydajnością.
Dzięki, dzięki temu zaoszczędziłem godziny nadmiernej komplikacji.
Hristo Stoyanov
10
Walczyłem z tym samym problemem. Rozwiązałem to za pomocą klasy statycznej, przechowując dowolne dane w HashMap. Ponadto korzystam z rozszerzenia standardowej klasy Activity, w której zastąpiłem metody onCreate onDestroy, aby ukryć transport danych i ich czyszczenie. Niektóre śmieszne ustawienia muszą zostać zmienione, np. Obsługa orientacji.
Adnotacja: Niedostarczenie ogólnych obiektów, które mają być przekazane do innej czynności, to ból w dupę. To tak, jakby strzelić sobie w kolano i mieć nadzieję na wygranie 100 metrów. „Parcable” nie jest wystarczającym substytutem. Rozśmiesza mnie ... Nie chcę implementować tego interfejsu do mojego wolnego od technologii API, ponieważ mniej chcę wprowadzić nową warstwę ... Jak to możliwe, że jesteśmy w programowaniu mobilnym tak daleko od nowoczesny paradygmat ...
Jest to przydatne, jeśli masz obiekty o zasięgu na poziomie aplikacji, tzn. Muszą być używane w całej aplikacji. TheParcelable metoda jest jeszcze lepsza, jeśli chcesz jawnie kontrolować zakres obiektu lub jeśli zakres jest ograniczony.
Pozwala to jednak uniknąć Intentscałkowitego użycia . Nie wiem czy ci odpowiadają. Innym sposobem, w jaki to wykorzystałem, jest intwysyłanie identyfikatorów obiektów poprzez zamiary i pobieranie obiektów, które mam w Mapach w Applicationobiekcie.
To nie jest właściwy sposób na robienie rzeczy, ponieważ obiekty mogą być zmienne, twój może działać, jeśli mówisz o obiekcie statycznym podczas cyklu życia aplikacji, ale czasami potrzebujemy pasywnych obiektów, które mogą być generowane za pomocą usługi internetowej, a więc stackoverflow.com / a / 2736612/716865
Muhannad A.Alhariri
Użyłem go z powodzeniem z obiektami generowanymi z usług sieciowych, mając zakres aplikacji, w Mapktórym obiekty są przechowywane i pobierane za pomocą identyfikatora. Jedynym prawdziwym problemem związanym z tym podejściem jest to, że Android po pewnym czasie usuwa pamięć, więc musisz sprawdzić wartości zerowe w swoim polu OnResume (myślę, że obiekty przekazane w zamierzeniu są utrwalane, ale nie jestem pewien). Poza tym nie uważam tego za znacznie gorszy.
Saad Farooq
To najlepsza odpowiedź. Pokazuje, w jaki sposób różne działania mogą odnosić się do tego samego modelu danych. Długo zajęło mi odkrycie tego!
Markus
6
w swoim modelu klasy (Object) zaimplementuj Serializable, na przykład:
lub klasa serializowalna creata, aby przejść do innego działania, cokolwiek chcesz przekazać.
UMAR
9
Pamiętaj tylko, aby nie kłaść dużych, grubych przedmiotów. Żywotność tego obiektu będzie taka sama jak żywotność aplikacji. I nigdy nie przechowuj wyświetleń. Ta metoda gwarantuje także wycieki pamięci.
Reno,
1
Ta odpowiedź jest przydatna, ale nie lepszym rozwiązaniem pod względem optymalizacji pamięci i zasobów
Atul Bhardwaj
1
To łamie zasady OOP, wprowadzając zmienne globalne. Nigdy nie wiadomo, w jakim są stanie, czy są ustawione, czy nie, są używane przez wiele wątków i trzeba poradzić sobie z tą złożonością. Zazwyczaj jest to dobry wyciek pamięci, ponieważ nawet nie wiadomo, kiedy uwolnić te zmienne. Nie mówiąc już, że wprowadza twarde bezpośrednie połączenie między różnymi modułami aplikacji.
afrish
2
WTF? Pozostałe dwie odpowiedzi są o wiele lepsze.
IcyFlame
4
możesz użyć metod putExtra (Serializable ..) i getSerializableExtra () do przekazywania i pobierania obiektów typu klasy; będziesz musiał oznaczyć klasę jako Serializowalną i upewnić się, że wszystkie zmienne członkowskie również są możliwe do serializacji ...
Wprowadź nazwę projektu: android-pass-object-to-activity
Pakcage: com.hmkcode.android
Zachowaj inne błędne wybory, idź Dalej, aż dojdziesz do końca
Przed rozpoczęciem tworzenia aplikacji musimy utworzyć klasę POJO „Osoba”, której użyjemy do przesłania obiektu z jednej czynności do drugiej. Zauważ, że klasa implementuje interfejs Serializable.
Person.java
package com.hmkcode.android;import java.io.Serializable;publicclassPersonimplementsSerializable{privatestaticfinallong serialVersionUID =1L;privateString name;privateint age;// getters & setters....@OverridepublicString toString(){return"Person [name="+ name +", age="+ age +"]";}}
Dwa układy dla dwóch działań
Activity_main.xml
<LinearLayoutxmlns:android="http://schemas.android.com/apk/res/android"xmlns:tools="http://schemas.android.com/tools"android:layout_width="match_parent"android:layout_height="match_parent"android:orientation="vertical"tools:context=".MainActivity"><LinearLayoutandroid:layout_width="fill_parent"android:layout_height="wrap_content"android:orientation="horizontal"><TextViewandroid:id="@+id/tvName"android:layout_width="100dp"android:layout_height="wrap_content"android:layout_gravity="center"android:gravity="center_horizontal"android:text="Name"/><EditTextandroid:id="@+id/etName"android:layout_width="wrap_content"android:layout_height="wrap_content"android:ems="10"><requestFocus/></EditText></LinearLayout><LinearLayoutandroid:layout_width="fill_parent"android:layout_height="wrap_content"android:orientation="horizontal"><TextViewandroid:id="@+id/tvAge"android:layout_width="100dp"android:layout_height="wrap_content"android:layout_gravity="center"android:gravity="center_horizontal"android:text="Age"/><EditTextandroid:id="@+id/etAge"android:layout_width="wrap_content"android:layout_height="wrap_content"android:ems="10"/></LinearLayout><Buttonandroid:id="@+id/btnPassObject"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_gravity="center_horizontal"android:text="Pass Object to Another Activity"/></LinearLayout>
package com.hmkcode.android;import android.os.Bundle;import android.app.Activity;import android.content.Intent;import android.view.View;import android.view.View.OnClickListener;import android.widget.Button;import android.widget.EditText;publicclassMainActivityextendsActivityimplementsOnClickListener{Button btnPassObject;EditText etName, etAge;@Overrideprotectedvoid onCreate(Bundle savedInstanceState){super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
btnPassObject =(Button) findViewById(R.id.btnPassObject);
etName =(EditText) findViewById(R.id.etName);
etAge =(EditText) findViewById(R.id.etAge);
btnPassObject.setOnClickListener(this);}@Overridepublicvoid onClick(View view){// 1. create an intent pass class name or intnet action name Intent intent =newIntent("com.hmkcode.android.ANOTHER_ACTIVITY");// 2. create person objectPerson person =newPerson();
person.setName(etName.getText().toString());
person.setAge(Integer.parseInt(etAge.getText().toString()));// 3. put person in intent data
intent.putExtra("person", person);// 4. start the activity
startActivity(intent);}}
2) AnotherActivity.java
package com.hmkcode.android;import android.app.Activity;import android.content.Intent;import android.os.Bundle;import android.widget.TextView;publicclassAnotherActivityextendsActivity{TextView tvPerson;@Overrideprotectedvoid onCreate(Bundle savedInstanceState){// TODO Auto-generated method stubsuper.onCreate(savedInstanceState);
setContentView(R.layout.activity_another);// 1. get passed intent Intent intent = getIntent();// 2. get person object from intentPerson person =(Person) intent.getSerializableExtra("person");// 3. get reference to person textView
tvPerson =(TextView) findViewById(R.id.tvPerson);// 4. display name & age on textView
tvPerson.setText(person.toString());}}
Korzystając z biblioteki Google Gson, możesz przekazać obiekt do innych działań. Właściwie przekonwertujemy obiekt w postaci ciągu json, a po przejściu do innej aktywności ponownie przekonwertujemy obiekt na taki jak ten
Example exampleObject=newExample(1,"hello");String jsonString =newGson().toJson(exampleObject);Intent nextIntent=newIntent(this,NextActivity.class);
nextIntent.putExtra("example",jsonString );
startActivity(nextIntent);
Do odczytu musimy wykonać operację odwrotną w NextActivity
Example defObject=newExample(-1,null);//default value to return when example is not availableString defValue=newGson().toJson(defObject);String jsonString=getIntent().getExtras().getString("example",defValue);//passed example objectExample exampleObject=newGson().fromJson(jsonString,Example.class);
Jeśli i tak masz klasę singleton (usługa fx), która działa jako brama do warstwy modelu, możesz ją rozwiązać, wprowadzając zmienną w tej klasie z pobierającymi i ustawiającymi.
privateService service;privateOrder order;@Overrideprotectedvoid onCreate(Bundle savedInstanceState){super.onCreate(savedInstanceState);
setContentView(R.layout.activity_quality);
service =Service.getInstance();
order = service.getSavedOrder();
service.setSavedOrder(null)//If you don't want to save it for the entire session of the app.}
To rozwiązanie nie wymaga serializacji ani innego „pakowania” danego obiektu. Ale będzie to korzystne tylko wtedy, gdy korzystasz z tego rodzaju architektury.
Jakie są wady tego podejścia? Wydaje się tak logiczny i smukły. Zawsze czytam, że nie powinieneś tego robić, ale nigdy nie otrzymuję dobrego wyjaśnienia, co może pójść nie tak.
Markus
Ponieważ nie mogę już edytować mojego komentarza: czy nie jest to jedyne możliwe rozwiązanie, aby uzyskać odwołanie do obiektu zamiast kopii? Muszę pobrać ten sam obiekt, a nie kopię!
Markus
Myślę, że jest to nieco odradzane z powodu wysokiego sprzężenia, do którego prowadzi. Ale tak, o ile widzę, takie podejście jest najbardziej realne, jeśli potrzebujesz rzeczywistego obiektu. Jak zawsze w programowaniu, możesz robić, co chcesz, po prostu chcesz to robić ostrożnie. To rozwiązanie działało dla mnie i wolę je, ponieważ i tak używam tej architektury.
Kitalda
W rzeczywistości rozszerzyłem klasę aplikacji i tam zapisałem swój model danych. W Intentach przekazałem tylko identyfikator obiektów danych, których można użyć do pobrania oryginalnego obiektu z klasy Application. Rozszerzona klasa aplikacji powiadamia również wszystkie obiekty korzystające z modelu danych, jeśli zmienia się ono za pomocą standardowej koncepcji detektora. Wiem, że pasuje to tylko do mojego przypadku, w którym muszę współużytkować model danych w całej aplikacji, ale w tym przypadku jest on doskonały i nie wymaga też klas statycznych i pól!
Markus
2
Zdecydowanie najłatwiejszy sposób na paczkowanie obiektów IMHO. Wystarczy dodać znacznik adnotacji nad obiektem, który ma być paczkowany.
Odpowiedzi:
Jeśli tylko przepuszczasz przedmioty, to Parcelable został do tego zaprojektowany. Wymaga nieco więcej wysiłku, niż użycie natywnej serializacji Javy, ale jest o wiele szybszy (i mam na myśli sposób, WAY szybszy).
Z dokumentacji prosty przykład implementacji to:
Zauważ, że w przypadku, gdy masz więcej niż jedno pole do pobrania z danej paczki, musisz to zrobić w tej samej kolejności, w jakiej je umieściłeś (czyli w podejściu FIFO).
Gdy masz swoje obiekty realizować
Parcelable
to tylko kwestia oddania ich do swoich zamiarów z putExtra () :Następnie możesz wyciągnąć je z powrotem za pomocą getParcelableExtra () :
Jeśli twoja klasa obiektów implementuje paczkowanie i szeregowalność, upewnij się, że wykonałeś rzut na jeden z poniższych:
źródło
Musisz serializować swój obiekt do pewnego rodzaju reprezentacji ciągu. Jedną z możliwych reprezentacji ciągów jest JSON, a jednym z najprostszych sposobów serializacji do / z JSON w Androidzie , jeśli mnie pytasz, jest Google GSON .
W takim przypadku po prostu wstawisz wartość zwracaną z ciągu
(new Gson()).toJson(myObject);
i pobierzesz wartość ciągu, a następnie użyjesz go,fromJson
aby z powrotem przekształcić go w obiekt.Jeśli twój obiekt nie jest zbyt skomplikowany, może nie być warty narzutu i zamiast tego możesz rozważyć przekazanie oddzielnych wartości obiektu.
źródło
String s = (new Gson().toJson(client));
Cli client = new Gson().fromJson(s, Cli.class);
Możesz wysłać obiekt możliwy do serializacji poprzez zamiar
źródło
Serializable
ale nieParcelable
jest, rzadko warto się nim męczyćParcelable
.W sytuacjach, w których wiesz, że będziesz przekazywać dane w aplikacji, użyj „globałów” (takich jak klasy statyczne)
Oto, co Dianne Hackborn (hackbod - inżynier oprogramowania Google na Androida) powiedział w tej sprawie:
źródło
Twoja klasa powinna implementować Serializable lub Parcelable.
Po zakończeniu możesz wysłać obiekt na putExtra
Aby uzyskać dodatki, musisz tylko zrobić
Jeśli twoja klasa implementuje Paczkowanie, użyj następnego
Mam nadzieję, że to pomoże: D
źródło
Serializable
jest niewłaściwa. Klasa możeParcelable
na przykład zaimplementować .Serializable
jest standardowym interfejsem Java,Parcelable
jest specyficzny dla Androida. Pod względem wydajności Parcelable jest bardziej wydajny: developerphil.com/parcelable-vs-serializableKrótka odpowiedź na szybką potrzebę
1. Zaimplementuj swoją klasę do postaci szeregowej.
Jeśli masz jakieś wewnętrzne klasy, nie zapomnij o ich wdrożeniu w Serializable !!
2. Wprowadź swój obiekt w zamiar
3. I odbierz swój przedmiot w drugiej klasie aktywności
źródło
jeśli twoja klasa obiektów implementuje
Serializable
, nie musisz nic więcej robić, możesz przekazać obiekt możliwy do serializacji.tego używam.
źródło
implementować serializowalne w twojej klasie
Następnie możesz przekazać ten obiekt w sposób zamierzony
W drugim ćwiczeniu możesz uzyskać takie dane
Ale gdy dane staną się duże, ta metoda będzie wolna.
źródło
Istnieje kilka sposobów uzyskiwania dostępu do zmiennych lub obiektów w innych klasach lub działaniu.
A. Baza danych
B. wspólne preferencje.
C. Serializacja obiektów.
D. Klasa, która może przechowywać wspólne dane, może zostać nazwana jako Common Utilities, zależna od Ciebie.
E. Przekazywanie danych przez intencje i interfejs paczkowany.
To zależy od potrzeb twojego projektu.
A. Baza danych
SQLite to baza danych Open Source, która jest wbudowana w system Android. SQLite obsługuje standardowe funkcje relacyjnej bazy danych, takie jak składnia SQL, transakcje i przygotowane wyciągi.
Samouczki - http://www.vogella.com/articles/AndroidSQLite/article.html
B. Wspólne preferencje
Załóżmy, że chcesz zapisać nazwę użytkownika. Tak więc będą teraz dwie rzeczy: kluczowa nazwa użytkownika, wartość wartości.
Jak przechowywać
Używając putString (), putBoolean (), putInt (), putFloat (), putLong () możesz zapisać żądany typ danych.
Jak pobrać
http://developer.android.com/reference/android/content/SharedPreferences.html
C. Serializacja obiektu
Serlizacja obiektów jest stosowana, jeśli chcemy zapisać stan obiektu, aby wysłać go przez sieć lub można go również użyć do własnych celów.
Używaj fasoli java i przechowuj w niej jako jedno z jego pól i używaj do tego getters i setter
JavaBeans to klasy Java, które mają właściwości. Traktuj właściwości jako zmienne instancji prywatnej. Ponieważ są prywatne, jedynym sposobem, aby uzyskać do nich dostęp spoza ich klasy, są metody w klasie. Metody zmieniające wartość właściwości nazywane są metodami ustawiającymi, a metody pobierające wartość właściwości nazywane są metodami pobierającymi.
Ustaw zmienną w swojej metodzie pocztowej za pomocą
Następnie użyj obiektu Serialzation, aby serializować ten obiekt, a w drugiej klasie deserializować ten obiekt.
W serializacji obiekt może być reprezentowany jako ciąg bajtów, który zawiera dane obiektu, a także informacje o typie obiektu i typach danych przechowywanych w obiekcie.
Po zapisaniu serializowanego obiektu w pliku można go odczytać z pliku i dokonać deserializacji, to znaczy informacje o typie i bajty reprezentujące obiekt oraz jego dane można wykorzystać do odtworzenia obiektu w pamięci.
Jeśli chcesz samouczek do tego, skorzystaj z tego linku
http://javawithswaranga.blogspot.in/2011/08/serialization-in-java.html
Uzyskaj zmienną w innych klasach
D. Wspólne narzędzia
Możesz samodzielnie stworzyć klasę, która może zawierać wspólne dane, których często potrzebujesz w swoim projekcie.
Próba
E. Przekazywanie danych przez zamiary
Zapoznaj się z tym samouczkiem, aby zapoznać się z tą opcją przekazywania danych.
http://shri.blog.kraya.co.uk/2010/04/26/android-parcel-data-to-pass-between-activities-using-parcelable-classes/
źródło
Aby to zrobić, możesz użyć Android BUNDLE.
Utwórz pakiet ze swojej klasy, taki jak:
Następnie przekaż ten pakiet za pomocą INTENT. Teraz możesz odtworzyć obiekt klasy, przekazując podobny pakiet
Zadeklaruj to w swojej klasie niestandardowej i użyj.
źródło
Dzięki za przesyłkę, ale znalazłem jeszcze jedno opcjonalne rozwiązanie
W ćwiczeniu pierwszym
Uzyskaj dane w działaniu 2
źródło
Używam Gsona z jego tak potężnym i prostym interfejsem API, aby przesyłać obiekty między czynnościami,
Przykład
2 funkcje dodajesz je do obiektów, które chcesz wysłać
Stosowanie
Wyślij obiekt od A do B.
Odbierz w B
Używam go prawie w każdym projekcie i nie mam problemów z wydajnością.
źródło
Walczyłem z tym samym problemem. Rozwiązałem to za pomocą klasy statycznej, przechowując dowolne dane w HashMap. Ponadto korzystam z rozszerzenia standardowej klasy Activity, w której zastąpiłem metody onCreate onDestroy, aby ukryć transport danych i ich czyszczenie. Niektóre śmieszne ustawienia muszą zostać zmienione, np. Obsługa orientacji.
Adnotacja: Niedostarczenie ogólnych obiektów, które mają być przekazane do innej czynności, to ból w dupę. To tak, jakby strzelić sobie w kolano i mieć nadzieję na wygranie 100 metrów. „Parcable” nie jest wystarczającym substytutem. Rozśmiesza mnie ... Nie chcę implementować tego interfejsu do mojego wolnego od technologii API, ponieważ mniej chcę wprowadzić nową warstwę ... Jak to możliwe, że jesteśmy w programowaniu mobilnym tak daleko od nowoczesny paradygmat ...
źródło
W pierwszej aktywności:
A w drugim:
Nie zapomnij ustawić niestandardowego obiektu na Serializable:
źródło
Innym sposobem na to jest użycie
Application
obiektu (android.app.Application). Zdefiniujesz to w swoimAndroidManifest.xml
pliku jako:Następnie możesz wywołać to z dowolnej aktywności i zapisać obiekt w
Application
klasie.W FirstActivity:
W SecondActivity wykonaj:
Jest to przydatne, jeśli masz obiekty o zasięgu na poziomie aplikacji, tzn. Muszą być używane w całej aplikacji. The
Parcelable
metoda jest jeszcze lepsza, jeśli chcesz jawnie kontrolować zakres obiektu lub jeśli zakres jest ograniczony.Pozwala to jednak uniknąć
Intents
całkowitego użycia . Nie wiem czy ci odpowiadają. Innym sposobem, w jaki to wykorzystałem, jestint
wysyłanie identyfikatorów obiektów poprzez zamiary i pobieranie obiektów, które mam w Mapach wApplication
obiekcie.źródło
Map
którym obiekty są przechowywane i pobierane za pomocą identyfikatora. Jedynym prawdziwym problemem związanym z tym podejściem jest to, że Android po pewnym czasie usuwa pamięć, więc musisz sprawdzić wartości zerowe w swoim polu OnResume (myślę, że obiekty przekazane w zamierzeniu są utrwalane, ale nie jestem pewien). Poza tym nie uważam tego za znacznie gorszy.w swoim modelu klasy (Object) zaimplementuj Serializable, na przykład:
i twoja pierwsza aktywność
i twoja druga aktywność (NewActivity)
powodzenia!!
źródło
Przekazywanie danych:
Odzyskiwanie danych:
źródło
najłatwiejszym rozwiązaniem, jakie znalazłem, jest ... utworzenie klasy ze statycznymi elementami danych z ustawiaczami getterów.
ustawić z jednego działania i uzyskać z innego działania tego obiektu.
aktywność A
aktywność b
źródło
możesz użyć metod putExtra (Serializable ..) i getSerializableExtra () do przekazywania i pobierania obiektów typu klasy; będziesz musiał oznaczyć klasę jako Serializowalną i upewnić się, że wszystkie zmienne członkowskie również są możliwe do serializacji ...
źródło
Utwórz aplikację na Androida
Plik >> Nowy >> Aplikacja na Androida
Wprowadź nazwę projektu: android-pass-object-to-activity
Pakcage: com.hmkcode.android
Zachowaj inne błędne wybory, idź Dalej, aż dojdziesz do końca
Przed rozpoczęciem tworzenia aplikacji musimy utworzyć klasę POJO „Osoba”, której użyjemy do przesłania obiektu z jednej czynności do drugiej. Zauważ, że klasa implementuje interfejs Serializable.
Person.java
Dwa układy dla dwóch działań
Activity_main.xml
activity_another.xml
Dwie klasy aktywności
1) ActivityMain.java
2) AnotherActivity.java
źródło
Korzystając z biblioteki Google Gson, możesz przekazać obiekt do innych działań. Właściwie przekonwertujemy obiekt w postaci ciągu json, a po przejściu do innej aktywności ponownie przekonwertujemy obiekt na taki jak ten
Rozważ taką klasę fasoli jak ta
Musimy przekazać obiekt klasy Przykład
Do odczytu musimy wykonać operację odwrotną w NextActivity
Dodaj tę zależność w stopniach
źródło
źródło
Wiem, że jest późno, ale to bardzo proste. Wszystko, co musisz zrobić, to pozwolić swojej klasie zaimplementować Serializable jak
wtedy możesz przejść do takiego celu
Aby to zrobić, po prostu zadzwoń
źródło
Jeśli i tak masz klasę singleton (usługa fx), która działa jako brama do warstwy modelu, możesz ją rozwiązać, wprowadzając zmienną w tej klasie z pobierającymi i ustawiającymi.
W ćwiczeniu 1:
W ćwiczeniu 2:
Czynny:
To rozwiązanie nie wymaga serializacji ani innego „pakowania” danego obiektu. Ale będzie to korzystne tylko wtedy, gdy korzystasz z tego rodzaju architektury.
źródło
Zdecydowanie najłatwiejszy sposób na paczkowanie obiektów IMHO. Wystarczy dodać znacznik adnotacji nad obiektem, który ma być paczkowany.
Przykład z biblioteki znajduje się poniżej https://github.com/johncarl81/parceler
źródło
Najpierw zaimplementuj Paczkę w swojej klasie. Następnie przekaż obiekt w ten sposób.
SendActivity.java
ReceiveActivity.java
Ciąg pakietu nie jest konieczny, po prostu ciąg musi być taki sam w obu działaniach
ODNIESIENIE
źródło
Rozpocznij kolejną czynność od tego parametru przekazywania parametrów poprzez Obiekt pakietu
Pobierz inną aktywność (YourActivity)
Jest to odpowiednie dla prostego rodzaju danych. Ale jeśli chcesz przesyłać złożone dane pomiędzy działaniami, najpierw musisz je serializować.
Tutaj mamy model pracownika
Możesz użyć biblioteki Gson lib dostarczonej przez Google do serializacji złożonych danych w ten sposób
źródło
W Koltinie
Dodaj rozszerzenie kotlin do swojego build.gradle.
Następnie utwórz swoją klasę danych w ten sposób.
Przekaż obiekt z zamiarem
Zdobądź obiekt z zamiarem
źródło
Najłatwiejszym i java sposobem jest: implementować serializable w twojej klasie pojo / model
Zalecane dla Androida dla widoku wydajności: uczyń model paczkowym
źródło
Najprościej byłoby po prostu użyć następującego, gdy element jest łańcuchem:
Do odbioru:
źródło