【问题标题】:Does the Activity need to be Serializable when sending a class that implements Serializable through Intent and putExtra?通过Intent和putExtra发送实现Serializable的类时Activity是否需要Serializable?
【发布时间】:2023-03-07 09:54:01
【问题描述】:

我一直在尝试将一个类的实例从一个 Activity 传递到另一个。

到目前为止,我只收到了java.io.NotSerializableException 异常。

起初,这些链接到我设置为扩展 Serializable 的类,当这些错误停止时,它们开始链接到我通过 Intent 和 putExtra 发送实例的 Activity。

这是导致问题的代码:

Intent i = new Intent(NewGame.this, GameActivity.class);
i.putExtra("existing", true);
i.putExtra("customClass", gh);<--- THIS is the line for the Serializable class I send
startActivity(i);<--- Here I get NotSerializableException

NotSerializableException 首先链接到 NewGame(Intent 所在的 Activity),然后在我尝试扩展可序列化后,它开始在 Button 和 RadioGroup(视图扩展)等字段上显示错误。

如果我让 NewGame 不实现 Serializable,我会回到 NewGame 作为发送意图的 Activity。

所以:

i.putExtra(String name, Serializable s) 是否需要发送 Intent 的 Activity 来实现 Serializable?如果不是,为什么 startActivity 会给我发送意图的 Activity 异常?

更多代码:

public class NewGame extends Activity implements View.OnClickListener, SeekBar.OnSeekBarChangeListener,
        RadioGroup.OnCheckedChangeListener, AdapterView.OnItemSelectedListener, Serializable{
    SeekBar sb; 
    TextView tvAI;
    Button start, custAI;<--- This gives an error for some reason
    int max = 9;
    int min = 1;
    int step = 1;
    RadioGroup uniSize, aiDiff;<--- This gives an error for some reason
    Spinner spinner;<-- This gives an error for some reason
    int diff = 0;
    public void onCreate(Bundle sis){
        super.onCreate(sis);
        setContentView(R.layout.startgame);
        initialization of etc views
    }

    //Irrelevant code between create and onCreate is removed

    private void create(){


        setContentView(R.layout.loading);

        Thread thread = new Thread() {

            @Override
            public void run() {
                try {
                    super.run();
                    sleep(500);  //initial tiny delay
                    //GameHandler implements serializable
                    GameHandler gh = new GameHandler(stars, NewGame.this, AIs);//The GameHandler constructor takes in: int, Context, int
                    (etc other code)
                    gh.initGen(ais, player);
                    gh.save();

                    IntentHandler i = new IntentHandler();
                    Intent i = new Intent(instance, GameActivity.class);
                    i.putExtra("existingGH", true);
                    i.putExtra("gameHandler", gh);<--- This is where the app would stop if the issue is related to fields in GameHandler(gh)
                    instance.startActivity(i);<--- THIS is where the app stops working. It shows an exception related to the fields of NewGame(the class the intent is sent from and this code is in)
                    Log.e("DEBUG", "Leaving Activity NewGame");
                    finish();
                    join();

                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        };
        thread.start();
    }

}

游戏处理器:

public class GameHandler implements Serializable{

    int stars;
    int AIEntities;
    private Context c;
    private int width, height;
    private Random r;
    private Game game;
    private Neutral n;

    /**
     * Load the game.
     * @param c
     */
    public GameHandler(Context c, Game game){
        this.game = game;
        this.c = c;
        (etc irrelevant code)

    }

    public GameHandler(int stars, Context c, int AIEntities){
        this.c = c;
        this.stars = stars;
        this.AIEntities = AIEntities;

        (etc initialization)
        ais = new ArrayList<>();


    }
    public void initGen(ArrayList<Entity> ais, Player player){
        this.ais = ais;
        this.player = player;

        generate();
        //
        save();
    }

    public void save(){
        //saving
    }

    Rect[] rect;
    private int sx, sy, sclas, smass;
    ArrayList<Stars> solar;
    public void generate() {
        ...
    }

    public ArrayList<Stars> getStars(){
        return solar;
    }

    public void render(Canvas c){
        //rendering
    }

   //Needs to be transient to avoid error(Entity causes error)
    public transient ArrayList<Entity> ais;
    (other code, not relevant)

}

堆栈跟踪:

     03-25 18:42:46.371 1423-2474/com.mypackage W/System.err: java.lang.RuntimeException: Parcelable encountered IOException writing serializable object (name = com.mypackage.game.GameHandler)
03-25 18:42:46.371 1423-2474/com.mypackage W/System.err:     at android.os.Parcel.writeSerializable(Parcel.java:1468)
            03-25 18:42:46.371 1423-2474/com.mypackage W/System.err:     at android.os.Parcel.writeValue(Parcel.java:1416)
            03-25 18:42:46.371 1423-2474/com.mypackage W/System.err:     at android.os.Parcel.writeArrayMapInternal(Parcel.java:686)
            03-25 18:42:46.371 1423-2474/com.mypackage W/System.err:     at android.os.BaseBundle.writeToParcelInner(BaseBundle.java:1330)
            03-25 18:42:46.371 1423-2474/com.mypackage W/System.err:     at android.os.Bundle.writeToParcel(Bundle.java:1079)
            03-25 18:42:46.371 1423-2474/com.mypackage W/System.err:     at android.os.Parcel.writeBundle(Parcel.java:711)
            03-25 18:42:46.371 1423-2474/com.mypackage W/System.err:     at android.content.Intent.writeToParcel(Intent.java:8778)
            03-25 18:42:46.371 1423-2474/com.mypackage W/System.err:     at android.app.ActivityManagerProxy.startActivity(ActivityManagerNative.java:3112)
            03-25 18:42:46.371 1423-2474/com.mypackage W/System.err:     at android.app.Instrumentation.execStartActivity(Instrumentation.java:1540)
            03-25 18:42:46.371 1423-2474/com.mypackage W/System.err:     at android.app.Activity.startActivityForResult(Activity.java:4283)
            03-25 18:42:46.371 1423-2474/com.mypackage W/System.err:     at android.app.Activity.startActivityForResult(Activity.java:4230)
            03-25 18:42:46.371 1423-2474/com.mypackage W/System.err:     at android.app.Activity.startActivity(Activity.java:4567)
            03-25 18:42:46.371 1423-2474/com.mypackage W/System.err:     at android.app.Activity.startActivity(Activity.java:4535)
            03-25 18:42:46.371 1423-2474/com.mypackage W/System.err:     at com.mypackage.NewGame$3.run(NewGame.java:320)
            03-25 18:42:46.371 1423-2474/com.mypackage W/System.err: Caused by: java.io.NotSerializableException: com.mypackage.NewGame
03-25 18:42:46.371 1423-2474/com.mypackage W/System.err:     at java.io.ObjectOutputStream.writeNewObject(ObjectOutputStream.java:1344)
            03-25 18:42:46.371 1423-2474/com.mypackage W/System.err:     at java.io.ObjectOutputStream.writeObjectInternal(ObjectOutputStream.java:1651)
            03-25 18:42:46.371 1423-2474/com.mypackage W/System.err:     at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:1497)
            03-25 18:42:46.371 1423-2474/com.mypackage W/System.err:     at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:1461)
            03-25 18:42:46.371 1423-2474/com.mypackage W/System.err:     at java.io.ObjectOutputStream.writeFieldValues(ObjectOutputStream.java:959)
            03-25 18:42:46.371 1423-2474/com.mypackage W/System.err:     at java.io.ObjectOutputStream.defaultWriteObject(ObjectOutputStream.java:360)
            03-25 18:42:46.371 1423-2474/com.mypackage W/System.err:     at java.io.ObjectOutputStream.writeHierarchy(ObjectOutputStream.java:1054)
            03-25 18:42:46.371 1423-2474/com.mypackage W/System.err:     at java.io.ObjectOutputStream.writeNewObject(ObjectOutputStream.java:1384)
            03-25 18:42:46.371 1423-2474/com.mypackage W/System.err:     at java.io.ObjectOutputStream.writeObjectInternal(ObjectOutputStream.java:1651)
            03-25 18:42:46.371 1423-2474/com.mypackage W/System.err:     at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:1497)
            03-25 18:42:46.371 1423-2474/com.mypackage W/System.err:     at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:1461)
            03-25 18:42:46.371 1423-2474/com.mypackage W/System.err:     at android.os.Parcel.writeSerializable(Parcel.java:1463)
            03-25 18:42:46.371 1423-2474/com.mypackage W/System.err:    ... 13 more

【问题讨论】:

  • 请给出完整的代码(序列化类和下一个发送数据的类)以便更多理解,然后我们建议任何解决问题的方法
  • 接收类不是问题。异常在 NewGame 中被@startActivity 捕获,并在 NewGame 字段上显示异常(因此询问 Activity 是否需要可序列化)。 GameHandler 现在确实显示任何异常并且也不包含任何相关的恶魔。我正在从 NewGame 添加相关代码。

标签: java android android-intent serialization


【解决方案1】:

i.putExtra(String name, Serializable s) 是否需要发送 Intent 的 Activity 来实现 Serializable?

不,但它确实意味着s不能引用活动或其他非Serializable的东西你需要采取措施来防止序列化从尝试序列化它们(例如,覆盖in the documentation 描述的方法)。

在 NewGame 类中的对象上触发,该类在 gh 中没有实例

是的,确实如此。就在这里:

private Context c;

首先,Context 不是 Serializable。其次,Activity 继承自 Contextc 是您的 NewGame 活动,因为您将其分配给 c

【讨论】:

  • 我对异常感到奇怪的是,它是在 NewGame 类中的对象上触发的,该类在 gh 中没有实例(我试图发送到不同 Activity 的类)跨度>
  • 更新了问题,查看我从活动中获取的代码。正在寻找 StackTrace,稍后会添加它
  • @LunarWatcher: "它在 gh 中没有实例" -- 好吧,您正在将一个实例传递给 GameHandler 构造函数。
  • 传入构造函数的实例没有存储在GameHandler中。它在构造函数中用于基本初始化,然后被处理掉。我认为这不会造成问题
  • 编辑:传递 NewGame 是为了上下文。 GameHandler 构造函数是int, context, int
猜你喜欢
  • 1970-01-01
  • 2011-05-28
  • 1970-01-01
  • 1970-01-01
  • 2013-02-26
  • 2013-12-30
  • 2019-09-23
  • 1970-01-01
  • 2012-12-29
相关资源
最近更新 更多