10

hello Java和Android專家。我有一個問題。 我正在製作基於XMPP的聊天應用程序。有幾件事讓我感到困惑。自定義對象是通過值傳遞還是通過片段和活動中的引用傳遞?

我有一個名爲Room_Structure的類,它實現了可串行化的。此課程有一個名爲currentRoom的對象。

如果我通過currentroom兩個片段之間的對象通過把它放在一個捆綁它的工作很好,令人驚訝的是它通過引用傳遞。我不知道這是爲什麼。它不應該像這樣。順便說一句我正在使用Android支持庫?

但是,如果我通過那個currentRoom活動之間的活動使用捆綁並將該捆綁意圖然後我遇到崩潰,每當我嘗試使用該意圖開始一個新的活動。

有關詳細說明以下是代碼

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; 
} 

上述類具有構造以及吸氣和setter。

現在這裏是我在做什麼:

認爲currentRoom對象已經填充,這裏是我如何傳遞到碎片

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(); 

從Fragment_Chat OnActivityCreated取回()像這樣的方法

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

現在,上面的代碼工作就好了片段。唯一的問題是對象的引用被傳遞給新的片段。這不是它應該如何表現。它應該只發送價值而不是參考。

這是我如何知道對象是通過引用

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

通過兩者具有相同的參考或地址。在調試

現在我不能複製在活動

這種行爲我有一個包含ExpandibleListView一個活動檢查出來。我已經通過從BaseExpandableListAdapter擴展它來實現此Expandablelistview的適配器。此適配器類名稱是Websites_ListAdapter.java。它還在其構造函數中傳遞了活動的上下文。 而且我在列表中可以點擊佈局。我想在點擊時開始一個活動。請不要問我爲什麼這麼做了一個漫長的故事。 我從Websites_ListAdapter發送這個對象這樣

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); 

,但我得到這個錯誤在logcat的這個時候,當我打電話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 

我知道有很多方法可以通過活動之間的對象,但我想知道爲什麼會發生這樣的,在後臺是什麼序列化呢?

任何有關此事的幫助,我們將不勝感激。

回答

2

不同之處在於,您不像創建片段那樣創建活動對象,而是要求系統執行此操作。您創建一個意圖,以便要求系統創建活動,意圖中的每件事都會被序列化,然後通過系統傳遞給新活動。無法在共享同一個對象的同時創建兩個活動。 如果你確實需要相同的對象引用,你總是可以創建一個單例。

+1

在序列化的情況下,它應該總是創建一個實例的副本。但是我的測試在序列化和去串聯化後顯示......兩個對象在片段的情況下都指向相同的實例。我不明白這怎麼可能。 – 2013-04-25 13:45:34

+1

@SaqibSaud你在片段和活動中引用相同的bungle對象。他們是一樣的。捆綁方法putSerializable不會序列化對象,直到您序列化捆綁包本身。當你從一個活動向另一個活動傳遞包時,它會被系統序列化。 – nicous 2013-04-29 17:48:54

+1

@SherazKhilji這是正常的java行爲。活動是不同的,因爲你總是需要序列化數據在它們之間進行通信。 – nicous 2013-04-29 17:58:00

4

如果您將查看Bundle源代碼,您會發現它使用Map來存儲對象,並且只會在Bundle本身序列化時序列化對象。

看來Bundle在傳遞到分片時不會被序列化。它可以是優化技巧或實現「bug」。

但是當你想開始新的活動Bundle將被序列化而不是反序列化。這就是爲什麼你只有這個例外的活動。

+0

感謝@ MatrixDev所以,你可以告訴我,我怎麼能解決這個問題。有沒有其他的方法來發送數據? – 2013-04-25 12:08:07

+1

您可以爲要傳遞的所有對象實現Serializable接口。不可序列化的對象(比如MultiUserChat)可以存儲在全局應用程序對象或靜態變量中。 – MatrixDev 2013-04-25 12:14:09

+0

但我們不能模仿與碎片相同的行爲嗎? – 2013-04-25 12:25:48

0

問題是在這裏:

Caused by: java.io.NotSerializableException: 

org.jivesoftware.smackx.muc.MultiUserChat 

答案是:

public Class MultiUserChat implements Serializable