-2

Im trying to develop a little android game and i'm having a hard time understanding how can i surpass this problem.

What i'm trying to do is send data between activities.To achieve that i'm using the intent extras. The data that im trying to send is an ArrayList<Item

Item.java

public abstract class Item implements Serializable {

    private String fieldA;
    private int fieldB;
      
     *getters and setters*
    
    abstract void use();
}

the use method will be different on each item so thats why im using abstract

e.g creation item

Item hpPotion = new Item() {
            @Override
            public void use() {
                player.setHealth(player.getHealth() + 10)
            }
        };

and then im getting an error when starting the new Activity

Intent intent = new Intent(HistoryActivity.this,BagActivity.class);
                    intent.putExtra("items",player.getItems());
                    someActivityResultLauncher.launch(intent,options);

StackTrace:

E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.example.decisions, PID: 22018
    java.lang.RuntimeException: Parcelable encountered IOException writing serializable object (name = com.example.decisions.HistoryActivity$7)
        at android.os.Parcel.writeSerializable(Parcel.java:2116)
        at android.os.Parcel.writeValue(Parcel.java:1886)
        at android.os.Parcel.writeList(Parcel.java:1095)
        at android.os.Parcel.writeValue(Parcel.java:1835)
        at android.os.Parcel.writeArrayMapInternal(Parcel.java:978)
        at android.os.BaseBundle.writeToParcelInner(BaseBundle.java:1629)
        at android.os.Bundle.writeToParcel(Bundle.java:1303)
        at android.os.Parcel.writeBundle(Parcel.java:1047)
        at android.content.Intent.writeToParcel(Intent.java:10871)
        at android.app.IActivityTaskManager$Stub$Proxy.startActivity(IActivityTaskManager.java:3887)
        at android.app.Instrumentation.execStartActivity(Instrumentation.java:1727)
        at android.app.Activity.startActivityForResult(Activity.java:5405)
        at androidx.activity.ComponentActivity.startActivityForResult(ComponentActivity.java:574)
        at androidx.core.app.ActivityCompat.startActivityForResult(ActivityCompat.java:237)
        at androidx.activity.ComponentActivity$2.onLaunch(ComponentActivity.java:208)
        at androidx.activity.result.ActivityResultRegistry$2.launch(ActivityResultRegistry.java:166)
        at com.example.decisions.HistoryActivity$2.onClick(HistoryActivity.java:96)
        at android.view.View.performClick(View.java:7559)
        at android.view.View.performClickInternal(View.java:7536)
        at android.view.View.access$3600(View.java:828)
        at android.view.View$PerformClick.run(View.java:28700)
        at android.os.Handler.handleCallback(Handler.java:938)
        at android.os.Handler.dispatchMessage(Handler.java:99)
        at android.os.Looper.loop(Looper.java:236)
        at android.app.ActivityThread.main(ActivityThread.java:7861)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:600)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:967)
     Caused by: java.io.NotSerializableException: com.example.decisions.HistoryActivity
        at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1240)
        at java.io.ObjectOutputStream.defaultWriteFields(ObjectOutputStream.java:1604)
        at java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1565)
        at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1488)
        at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1234)
        at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:354)
        at android.os.Parcel.writeSerializable(Parcel.java:2111)
        at android.os.Parcel.writeValue(Parcel.java:1886) 
        at android.os.Parcel.writeList(Parcel.java:1095) 
        at android.os.Parcel.writeValue(Parcel.java:1835) 
        at android.os.Parcel.writeArrayMapInternal(Parcel.java:978) 
        at android.os.BaseBundle.writeToParcelInner(BaseBundle.java:1629) 
        at android.os.Bundle.writeToParcel(Bundle.java:1303) 
        at android.os.Parcel.writeBundle(Parcel.java:1047) 
        at android.content.Intent.writeToParcel(Intent.java:10871) 
        at android.app.IActivityTaskManager$Stub$Proxy.startActivity(IActivityTaskManager.java:3887) 
        at android.app.Instrumentation.execStartActivity(Instrumentation.java:1727) 
        at android.app.Activity.startActivityForResult(Activity.java:5405) 
        at androidx.activity.ComponentActivity.startActivityForResult(ComponentActivity.java:574) 
        at androidx.core.app.ActivityCompat.startActivityForResult(ActivityCompat.java:237) 
        at androidx.activity.ComponentActivity$2.onLaunch(ComponentActivity.java:208) 
        at androidx.activity.result.ActivityResultRegistry$2.launch(ActivityResultRegistry.java:166) 
        at com.example.decisions.HistoryActivity$2.onClick(HistoryActivity.java:96) 
        at android.view.View.performClick(View.java:7559) 
        at android.view.View.performClickInternal(View.java:7536) 
        at android.view.View.access$3600(View.java:828) 
        at android.view.View$PerformClick.run(View.java:28700) 
        at android.os.Handler.handleCallback(Handler.java:938) 
        at android.os.Handler.dispatchMessage(Handler.java:99) 
        at android.os.Looper.loop(Looper.java:236) 
    ```

What would be the best approach to solve my problem?

Thank you all

1 Answers1

-1

You're trying to serialize an Activity, either directly or indirectly (something you're trying to Serialize has a reference to an Activity). That's not possible, because Activity does not implement Serializable. To properly implement Serializable, all of your member variables must either be primitives or implement Serializable themselves.

Edit: If Item is a subclass of Activity, it may be picking up the implicit parent reference. In that case, make it a static class.

user207421
  • 305,947
  • 44
  • 307
  • 483
Gabe Sechan
  • 90,003
  • 9
  • 87
  • 127
  • If `Item` is a subclass of `Activity` there is something seriously wrong with the design, but making it a static class won't fix anything, even if it's possible. – user207421 Feb 28 '22 at 06:35
  • @user207421 I agree it shouldn't be, but if for some reason it is (most likely due to a newbie not knowing how subclasses work and just adding it in one file), then making it static would work- it removes the inherent parent reference which causes the problem. – Gabe Sechan Feb 28 '22 at 06:39
  • No it doesn't. Making a class `static` implies that it was otherwise 'inner', and therefore had an implicit reference *to the outer object.* Making it `static` will fix that, but it won't change its behaviour w.r.t. the parent class, to which BTW there is no 'implicit reference'. In any case the exception names `HistoryActivity`, not `Item`. – user207421 Feb 28 '22 at 07:23
  • @user207421 So you've just proven you completely don't understand Java and inner classes. A static inner class removes the implicit reference to the parent class. That's the entire purpose of a static inner class. It's basically telling the compiler "I know this is an inner class, but I don't want it to be able to access variables of the parent, its here only for organizational purposes" – Gabe Sechan Feb 28 '22 at 15:38
  • No, *you've* proven that you are confused between inheritance and inner classes. Your answer talks about `Item` being a subclass of `Activity` rather than an inner class of it. All the other stuff you claim I don't know I have already stated here. NB ['static inner' is a contradiction in terms](https://docs.oracle.com/javase/specs/jls/se8/html/jls-8.html#jls-8.1.3). NB 2 It is possible, although probably pointless, to serialize a subclass of `Activity` as long as the subclass `implements Serializable`. Your answer and comments are seriously confused. – user207421 Mar 01 '22 at 00:27
  • `Serializable` is an interface, so I don't know what you mean by 'subclass of `Serializable`', nor by 'generalize' it, but if you mean 'serialize a subclass of a non-serializable class' you can indeed do that, and it is done every day: *vide* the fact that `java.lang.Object` is not `Serializable`. You should have corrected your mistyping, at several points, not just one, instead of arguing and especially instead of shooting the messenger. Abuse reported. – user207421 Mar 01 '22 at 06:15