3

I'm trying to use Parcelable classes to give a Stack from an activity to another. In order to do this I defined MyStack and MyVector3 in the following way. This is then included in a Model class.

Model class

public class Model implements Parcelable{
    public List<MyStack> surfaces;
    public Info info;

    public Model (){}
    public Model(List<MyStack> surf){
       surfaces = surf;
    }

    public void setInfo(Info i){
        info=i;
    }

    public Info getInfo(){
        return info;
    }

    public List<MyStack> getSurfaces(){
        return this.surfaces;
    }

    public int numSurfaces(){
        return surfaces.size();
    }

    public int describeContents() {
        return 0;
    }

    public void writeToParcel(Parcel out, int flags) {
        out.writeTypedList(surfaces);
        //Parcelable infoP = ((Parcelable) info);
        //out.writeParcelable(infoP, 0);
    }

    public static final Parcelable.Creator<Model> CREATOR
        = new Parcelable.Creator<Model>() {
        public Model createFromParcel(Parcel in) {
            return new Model(in);
        }

        public Model[] newArray(int size) {
            return new Model[size];
        }
    };

    private Model(Parcel in) {
        surfaces = new ArrayList<MyStack>();
        in.readTypedList(surfaces, MyStack.CREATOR);
        //info = in.readParcelable(Info.class.getClassLoader());
    }

    public class Info{
        String title;
        String descr;

        public Info(String t, String d){
            title=t;
            descr=d;
        }

        public Info(String t){
            title=t;
        }

        public void setDescr(String d){
            descr=d;
        }
    }
}

MyStack class

public class MyStack implements Parcelable {
    public Stack<MyVector3> stack;

    public MyStack(MyStack ms){
        this.stack=ms.stack;
    }

    public MyStack(Stack s){
        stack= s;
    }

    public Stack getStack(){
        return this.stack;
    }

    public int describeContents() {
        return 0;
    }

    public void writeToParcel(Parcel out, int flags) {
        out.writeTypedList(stack);
    }

    public static final Parcelable.Creator<MyStack> CREATOR
        = new Parcelable.Creator<MyStack>() {
        public MyStack createFromParcel(Parcel in) {
            return new MyStack(in);
        }

        public MyStack[] newArray(int size) {
            return new MyStack[size];
        }
    };

    private MyStack(Parcel in) {
        stack= new Stack<MyVector3>();
        in.readTypedList(stack, MyVector3.CREATOR);
    }
}

MyVector3 class

public class MyVector3 extends Vector3 implements Parcelable {
    public Vector3 vector;

    public MyVector3(Vector3 v){
        vector=v;
    }

    public MyVector3(double x, double y, double z){
        vector= new Vector3(x,y,z);
    }

    public Vector3 getVector(){
        return this.vector;
    }

    public int describeContents() {
        return 0;
    }

    public void writeToParcel(Parcel out, int flags) {
        out.writeDoubleArray(new double[]{
            this.x,
            this.y,
            this.z});
    }

    public static final Parcelable.Creator<MyVector3> CREATOR
        = new Parcelable.Creator<MyVector3>() {
        public MyVector3 createFromParcel(Parcel in) {
            return new MyVector3(in);
        }

        public MyVector3[] newArray(int size) {
            return new MyVector3[size];
        }
    };

    private MyVector3(Parcel in) {
        double[] data = new double[3];
        in.readDoubleArray(data);

        this.x= data[0];
        this.y= data[1];
        this.z= data[2];
    }
}

This is the intent creation, where the model is well populated and I get all values correctly from Logs

Model model= new Model(surfaces);

    Intent intent = new Intent(this, EditorPresenter.class);
    intent.putExtra("model", model);
    startActivity(intent);

And where I use it

Intent intent = getIntent();
    model= intent.getParcelableExtra("model");
    MyStack[] sf = model.surfaces.toArray(new MyStack[model.numSurfaces()]);
    //surf = new Stack();
    surf = new Stack[model.numSurfaces()];
    Log.i(TAG, "ss="+Integer.toString(sf.length));
    for(int s=0; s<sf.length; s++) {
        Log.i(TAG, "s="+Integer.toString(s));
        Stack st= new Stack();
        Log.i(TAG, "vv="+Integer.toString(sf[s].getStack().size()));
        for(int v=0; v<sf[s].getStack().size(); v++) {
            Log.i(TAG, "v="+Integer.toString(v) +sf[s].stack.elementAt(v).getVector().toString());  //NullPointerException
            MyVector3 mv = (MyVector3) sf[s].stack.elementAt(v);
            if(mv!=null) st.add(mv.getVector());
        }
        surf[s]=st;
    }

But I get the following error:

java.lang.ClassCastException: com.modelrenderer.MyVector3$1 cannot be cast to com.modelrenderer.MyVector3

I really can't figure out which is the problem, but I'm very new to Android programmation expecially using Parcelable classes. Any help is really appreciated.

EDIT: I updated class with the current state

current error is NullPointerException on whatever I do with Vector3 item.

java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.String org.rajawali3d.math.vector.Vector3.toString()' on a null object reference
Nisse Engström
  • 4,738
  • 23
  • 27
  • 42

1 Answers1

1

The bit in the error message that gives you a clue as to what's going wrong is the $1. This notation is used when referring to an anonymous (inner) class - since it's declared "on-the-fly", it doesn't have a name of its own the compiler can use.

In your particular case, it looks like it means your CREATOR variable. So, in your for-loop, the item is one of those Parcelable.Creator<MyVector3> instances, but you're trying to cast it to a MyVector3 instance, hence the ClassCastException. You should be able to confirm this by simply debugging and "inspecting" what your sf[s].stack.elementAt(s) expression evaluates to. (Or, if you're not using an IDE that lets you debug, use a log statement, or print statement, to output the name of the class of that object.)

Recommendations: 1) Use better naming. Calling things s, sf, mv, etc., doesn't help other people to read your code. (And code will be read many more times than you'll write it.) 2) Read up on encapsulation. Learn to use accessors instead of making every instance variable public.

Community
  • 1
  • 1
Amos M. Carpenter
  • 4,848
  • 4
  • 42
  • 72
  • Thank you for the tips. Seems like there's something wrong with Parcelable classes then, because I'm supposed to have a Vector3 there and not a Parcelable.Creator – Antonio Iacobucci Feb 22 '16 at 11:00
  • Solved last problem but I get `java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.String org.rajawali3d.math.vector.Vector3.toString()' on a null object reference` on whatever I try to do with vectors. So i probably get a bugged model from the Intent or something is missing. – Antonio Iacobucci Feb 22 '16 at 13:56
  • Again - your best bet is debugging and stepping through your code, inspecting values to see what it's doing. This is a fundamental skill you'll need to use over and over if you're going to be writing more code. From your edited comment, it sounds like you're not initialising your vectors properly, hence the references are `null` when you try to invoke methods on them. It would also probably help both yourself and anyone here on SO trying to help you if you could condense your problem to a [minimal, complete, and verifiable example](http://stackoverflow.com/help/mcve). – Amos M. Carpenter Feb 22 '16 at 14:00
  • I just updated the code from the question. I did all day attempts with Logs, but the problem is proably in the Parcelable classes, since I don't get the correct model from the intent. I don't think i can minimize more the code I gave you, because all the three classes are needed to the intent. – Antonio Iacobucci Feb 22 '16 at 14:05
  • Please don't change the goal posts on the question. If my answer helped solve your original problem, please accept it and _ask a new question for your new problem_. – Amos M. Carpenter Feb 22 '16 at 14:10