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