10

こんにちは、Java と Android のエキスパートです。問題があります。XMPP ベースのチャット アプリケーションを作成しています。私を混乱させていることがいくつかあります。

Serializableを実装する Room_Structure という名前のクラスがあります。このクラスにはcurrentRoomという名前のオブジェクトがあります。

currentroomオブジェクトをバンドルに入れて 2 つのフラグメント間で渡している場合、正常に動作し、驚くべきことに参照によって渡されます。それがなぜなのかわかりません。このように振る舞うべきではありません。ところで私は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;
}

上記のクラスには、ゲッターとセッターだけでなく、コンストラクターもあります。

今ここに私がやっていることがあります:

currentRoom オブジェクトが既に取り込まれていることを考慮してください。これが 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();

このように Fragment_Chat OnActivityCreated() メソッドから取得する

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

これで、上記のコードはFragmentsに対して問題なく動作します。唯一の問題は、オブジェクトの参照が新しいフラグメントに渡されることです。これは、実際に動作する方法ではありません。参照ではなく値を送信するだけです。

オブジェクトが参照渡しであることを知る方法は次のとおりです

Sending Object : com.software.chat.Classes.Room_Structure@425585e8
Recieved Object: com.software.chat.Classes.Room_Structure@425585e8

どちらも同じ参照またはアドレスを持っています。デバッグ中にチェックアウトしました

今、アクティビティでこの動作を再現できません

ExpandibleListView を含むアクティビティがあります。BaseExpandableListAdapter から拡張することで、この Expandiblelistview のアダプターを実装しました。このアダプター クラス名は 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);

しかし、今回はActivityContext.startActivity(i)を呼び出すと、Logcatでこのエラーが発生します

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

アクティビティ間でオブジェクトを渡すには多くの方法があることは知っていますが、なぜこのように行われるのか、シリアライズ可能がバックグラウンドで何をするのかを知りたいですか?

この問題に関するヘルプは大歓迎です。

4

3 に答える 3

4

Bundleソースを調べると、オブジェクトの保存に Map を使用し、Bundle 自体がシリアル化されている場合にのみオブジェクトをシリアル化することがわかります。

フラグメントに渡すと Bundle がシリアライズされていないようです。最適化のトリックまたは実装の「バグ」である可能性があります。

ただし、新しいアクティビティを開始する場合、バンドルはシリアル化され、逆シリアル化されます。そのため、アクティビティに対してのみこの例外があります。

于 2013-04-25T11:56:55.433 に答える