10

hello Eksperci Java i Android. Mam problem. Tworzę aplikację czatu opartą na XMPP. Jest kilka rzeczy, które mnie mylą.Czy obiekty niestandardowe zostały przekazane według wartości lub przekazane przez odniesienie w fragmentach i działaniach?

Mam klasę o nazwie Room_Structure, która implementuje Serializable. Ta klasa ma obiekt o nazwie currentRoom.

Jeśli przechodzę obok obiektu currentroom obiekt między dwoma fragmentami, umieszczając go w pakiecie, działa dobrze i zaskakująco, jest przekazywany przez odniesienie. Nie wiem, dlaczego tak jest. To nie powinno się tak zachowywać. btw używam biblioteki pomocy Androida?

Ale jeśli jestem przechodzącej że currentRoom Przedmiotem między czynności wykorzystujących wiązkę i wprowadzanie tego zawiniątko w intencji następnie otrzymuję awarię ilekroć próbuję rozpocząć nową działalność z użyciem tego zamiaru.

uzyskać więcej Opis Oto kod

public class Room_Structure implements Serializable { 


    private static final long serialVersionUID = 1L; 
    private String Rname; 
    private ArrayList<Message_Pattern> msg_list; 
    private MultiUserChat XmppSession; 
    private boolean Background; 
    private boolean Modified; 
    private boolean Destroyed; 
} 

Powyższa klasa ma konstruktorów jak getter i ustawiające.

Teraz Oto co robię:

uważają, że obiekt currentRoom została już wypełniona i tutaj jest jak jestem przekazaniem go do Fragment

Bundle b = new Bundle(); 
    b.putSerializable("RoomObject", currentRoom); 
    Fragment_Chat newChat = new Fragment_Chat(); 
    newChat.setArguments(b); 
    FragmentManager fm = getChildFragmentManager(); 
    FragmentTransaction ft = fm.beginTransaction(); 
    ft.replace(R.id.fl_chatFragment, newChat); 
    ft.addToBackStack(null); 
    ft.commit(); 

pobierania go z Fragment_Chat OnActivityCreated() Metoda taka jak ta

Bundle extras = getArguments(); 
Room_Structure recievedRoom = (Room_Structure) extras.getSerializable("RoomObject"); 

Teraz powyższy kod działa poprawnie dla Fragmenty. jedynym problemem jest to, że referencja obiektu jest przekazywana do nowego fragmentu. Co nie powinno tak naprawdę zachowywać się. Powinien po prostu wysłać wartość, a nie referencję.

Oto jak wiem, że obiekty są przekazywane przez referencję

Sending Object : [email protected] 
Recieved Object: [email protected] 

oba mają taką samą nazwę lub adres. Sprawdziliśmy to podczas debugowanie

Teraz cant replikować to zachowanie w działaniach

mam aktywny, który zawiera ExpandibleListView. Zaimplementowałem adapter dla tego rozszerzenia Expandiblelistview, rozszerzając go z BaseExpandableListAdapter. Ta nazwa klasy adaptera to Websites_ListAdapter.java. Jest również przekazywany kontekst aktywności w swoim konstruktorze. I zrobiłem układ, który można kliknąć na liście. Chcę rozpocząć działanie po kliknięciu. proszę, nie pytaj dlaczego to zrobiłem, to długa historia. piszę ten obiekt z tego Websites_ListAdapter jak ten

Intent i=new Intent(ActivityContext, ChatScreen.class); 
    Bundle b = new Bundle(); 
    b.putSerializable("RoomObject", currentRoom); 
    i.putExtras(b); 
    i.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); 
    ActivityContext.startActivity(i); 

ale pojawia się ten błąd w logcat tym czasie, gdy zgłoszę ActivityContext.startActivity (i)

04-25 15:38:07.474: E/AndroidRuntime(10250): FATAL EXCEPTION: main 
04-25 15:38:07.474: E/AndroidRuntime(10250): java.lang.RuntimeException: Parcelable encountered IOException writing 

serializable object (name = com.software.chat.Classes.Room_Structure) 
04-25 15:38:07.474: E/AndroidRuntime(10250): at android.os.Parcel.writeSerializable(Parcel.java:1279) 
04-25 15:38:07.474: E/AndroidRuntime(10250): at android.os.Parcel.writeValue(Parcel.java:1233) 
04-25 15:38:07.474: E/AndroidRuntime(10250): at android.os.Parcel.writeMapInternal(Parcel.java:591) 
04-25 15:38:07.474: E/AndroidRuntime(10250): at android.os.Bundle.writeToParcel(Bundle.java:1619) 
04-25 15:38:07.474: E/AndroidRuntime(10250): at android.os.Parcel.writeBundle(Parcel.java:605) 
04-25 15:38:07.474: E/AndroidRuntime(10250): at android.content.Intent.writeToParcel(Intent.java:6814) 
04-25 15:38:07.474: E/AndroidRuntime(10250): at android.app.ActivityManagerProxy.startActivity 

(ActivityManagerNative.java:1910) 
04-25 15:38:07.474: E/AndroidRuntime(10250): at android.app.Instrumentation.execStartActivity(Instrumentation.java:1415) 
04-25 15:38:07.474: E/AndroidRuntime(10250): at android.app.Activity.startActivityForResult(Activity.java:3446) 
04-25 15:38:07.474: E/AndroidRuntime(10250): at android.app.Activity.startActivityForResult(Activity.java:3407) 
04-25 15:38:07.474: E/AndroidRuntime(10250): at android.support.v4.app.FragmentActivity.startActivityForResult 

(FragmentActivity.java:817) 
04-25 15:38:07.474: E/AndroidRuntime(10250): at android.app.Activity.startActivity(Activity.java:3617) 
04-25 15:38:07.474: E/AndroidRuntime(10250): at android.app.Activity.startActivity(Activity.java:3585) 
04-25 15:38:07.474: E/AndroidRuntime(10250): at com.software.chat.Adapters.Websites_ListAdapter$1.onClick 

(Websites_ListAdapter.java:211) 
04-25 15:38:07.474: E/AndroidRuntime(10250): at android.view.View.performClick(View.java:4211) 
04-25 15:38:07.474: E/AndroidRuntime(10250): at android.view.View$PerformClick.run(View.java:17267) 
04-25 15:38:07.474: E/AndroidRuntime(10250): at android.os.Handler.handleCallback(Handler.java:615) 
04-25 15:38:07.474: E/AndroidRuntime(10250): at android.os.Handler.dispatchMessage(Handler.java:92) 
04-25 15:38:07.474: E/AndroidRuntime(10250): at android.os.Looper.loop(Looper.java:137) 
04-25 15:38:07.474: E/AndroidRuntime(10250): at android.app.ActivityThread.main(ActivityThread.java:4898) 
04-25 15:38:07.474: E/AndroidRuntime(10250): at java.lang.reflect.Method.invokeNative(Native Method) 
04-25 15:38:07.474: E/AndroidRuntime(10250): at java.lang.reflect.Method.invoke(Method.java:511) 
04-25 15:38:07.474: E/AndroidRuntime(10250): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run 

(ZygoteInit.java:1006) 
04-25 15:38:07.474: E/AndroidRuntime(10250): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:773) 
04-25 15:38:07.474: E/AndroidRuntime(10250): at dalvik.system.NativeStart.main(Native Method) 
04-25 15:38:07.474: E/AndroidRuntime(10250): Caused by: java.io.NotSerializableException: 

org.jivesoftware.smackx.muc.MultiUserChat 
04-25 15:38:07.474: E/AndroidRuntime(10250): at java.io.ObjectOutputStream.writeNewObject(ObjectOutputStream.java:1364) 
04-25 15:38:07.474: E/AndroidRuntime(10250): at java.io.ObjectOutputStream.writeObjectInternal 

(ObjectOutputStream.java:1671) 
04-25 15:38:07.474: E/AndroidRuntime(10250): at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:1517) 
04-25 15:38:07.474: E/AndroidRuntime(10250): at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:1481) 
04-25 15:38:07.474: E/AndroidRuntime(10250): at java.io.ObjectOutputStream.writeFieldValues(ObjectOutputStream.java:979) 
04-25 15:38:07.474: E/AndroidRuntime(10250): at java.io.ObjectOutputStream.defaultWriteObject 

(ObjectOutputStream.java:368) 
04-25 15:38:07.474: E/AndroidRuntime(10250): at java.io.ObjectOutputStream.writeHierarchy(ObjectOutputStream.java:1074) 
04-25 15:38:07.474: E/AndroidRuntime(10250): at java.io.ObjectOutputStream.writeNewObject(ObjectOutputStream.java:1404) 
04-25 15:38:07.474: E/AndroidRuntime(10250): at java.io.ObjectOutputStream.writeObjectInternal 

(ObjectOutputStream.java:1671) 
04-25 15:38:07.474: E/AndroidRuntime(10250): at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:1517) 
04-25 15:38:07.474: E/AndroidRuntime(10250): at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:1481) 
04-25 15:38:07.474: E/AndroidRuntime(10250): at android.os.Parcel.writeSerializable(Parcel.java:1274) 
04-25 15:38:07.474: E/AndroidRuntime(10250): ... 24 more 

Wiem, że istnieje wiele sposobów, aby zdać obiektów między działań, ale chcę wiedzieć, dlaczego tak się dzieje w ten sposób i co robi serializable zrobić w tle?

Każda pomoc w tej sprawie jest bardzo doceniana.

Odpowiedz

2

Różnica polega na tym, że nie tworzy się obiektu aktywności w taki sam sposób jak fragmentów, dlatego prosimy system, aby to zrobił. Tworzysz intencję, aby poprosić system o utworzenie działania, każda rzecz w intencji jest serializowana, a następnie przekazywana przez system do nowej aktywności. Nie można utworzyć dwóch działań jednocześnie dzieląc ten sam obiekt. Jeśli naprawdę potrzebujesz tego samego odniesienia do obiektu, zawsze możesz utworzyć singleton.

+1

W przypadku serializacji zawsze należy utworzyć kopię instancji. ale mój test pokazuje po serializacji i deklizacji ... oba obiekty odnoszą się do tego samego wystąpienia w przypadku fragmentów. Nie rozumiem, jak to możliwe. –

+1

@SaqibSaud odwołujesz się do tego samego obiektu-bibeloty w fragmencie i aktywności. Oni są tacy sami. Metoda putSerializable w pakiecie nie powoduje serializacji obiektu, dopóki nie serializuje samego pakietu. Kiedy przekazujesz pakiet w zamierzeniu z jednej aktywności do drugiej, zostaje on spersonalizowany przez system. – nicous

+1

@SherazKhilji to normalne zachowanie java. Działania są różne, ponieważ zawsze trzeba szeregować dane, aby się między nimi komunikować. – nicous

4

Jeśli zajrzysz do źródeł Bundle zobaczysz, że używa mapy do przechowywania obiektów i serializuje obiekty tylko wtedy, gdy sam Pakiet jest serializowany.

Wygląda na to, że Pakiet nie jest serializowany po przekazaniu do fragmentów. Może to być sztuczka optymalizacyjna lub "błąd" implementacji.

Ale kiedy chcesz rozpocząć nową działalność, Pakiet będzie serializowany i deserializowany. Właśnie dlatego ten wyjątek dotyczy tylko działań.

+0

Dzięki @ MatrixDev więc możesz mi powiedzieć jak mogę rozwiązać ten problem. Czy istnieje alternatywne podejście do wysyłania danych? –

+1

można wdrożyć interfejs Serializable dla wszystkich obiektów, które chcesz przekazać. Obiekty nie podlegające serializacji (takie jak MultiUserChat w twoim przypadku) mogą być przechowywane w globalnym obiekcie aplikacji lub statycznych zmiennych. – MatrixDev

+0

Ale czy nie możemy naśladować takiego samego zachowania jak w przypadku Fragmentów? –

0

Problem jest tutaj:

Caused by: java.io.NotSerializableException: 

org.jivesoftware.smackx.muc.MultiUserChat 

Odpowiedź brzmi:

public Class MultiUserChat implements Serializable 
Powiązane problemy