Question

I have the following classes: Experiment and Measurements. I pass a HashMap containing Experiment objects as a value, and their Experiment.getExperimentName as a key, between Android activities.

These Experiment objects in turn contain a HashMap of Measurements objects. This HashMap has a the Measurements objects as a value, and their Measurements.getMeasurements as a key.

These Measurements objects then contain an ArrayList of doubles.

I've tried many variations of using bundle or directly putting in a parcel, but I keep getting a "ClassNotFoundException when unmarshalling: nl.bioinf.thema12.labpal.objects.Measurements" when I read the HashMap in the new activity.

How Would I correctly implement parcel/parcelable?

The Experiment Class:

package nl.bioinf.thema12.labpal.objects;
import java.util.HashMap;
//import java.util.Set;

import android.os.Bundle;
import android.os.Parcel;
import android.os.Parcelable;

/**
 * @author roy
 * a class which describes an experiment
 */
public class Experiment implements Parcelable{
    private String experimentName = "";
    private HashMap<String,Measurements> measurements = new HashMap<String,Measurements>();

    //every Experiment needs a name to make it unique
    public Experiment(String experimentName) {
        this.experimentName=experimentName;
    }

    /**
     * a method which adds values to a measurement
     * @param   measurementName the name of the measurement you want to write a value to
     * @param   measurement the value of the measurement you want to add
     * @return  the sequence from the fasta
     */
    public void addValueToMeasurements(String measurementName, double measurement){
        //try to add the measurement
        if(measurements.get(measurementName)== null){
            Measurements m = new Measurements(measurementName);
            m.addMeasurement(measurement);
            measurements.put(measurementName,m);
        }
        //if the measurement does not exist, create it
        else{
            measurements.get(measurementName).addMeasurement(measurement);  
        }
    }
    /**
     * a method which returns the experiment name
     * @return  the experiment name
     */ 
    public String getExperimentName(){
        return experimentName;
    }



    //This makes the object parselable, I don't understand why
    /**
     * a constructor for the parcelable variant of the object
     */     
    public Experiment(Parcel in){
        measurements = new HashMap<String,Measurements>();
        readFromParcel(in);
    }

    @Override
    public int describeContents() {
        // TODO Auto-generated method stub
        return 0;
    }

    @Override
    /**
     * a method which writes the objects to a parcel
     */ 
    public void writeToParcel(Parcel dest, int flags) {
        //dest.writeString(experimentName);
        //for(String s: (Set<String>)measurements.keySet()){
            //dest.writeString(s);
            //dest.writeValue(measurements.get(s));
        //}
        Bundle b = new Bundle();
        b.putString("experimentName", experimentName);
        b.putSerializable("measurements", measurements);
        dest.writeBundle(b);
    }

    /**
     * a method which reads from a parcel
     */ 
    public void readFromParcel(Parcel in){
        //experimentName = in.readString();
        Bundle b = in.readBundle();
        experimentName = b.getString("experimentName");
        measurements = (HashMap<String, Measurements>)b.getSerializable("measurements");
    }

    /**
     * generic parcelable creator method
     */ 
    public static final Parcelable.Creator CREATOR =
        new Parcelable.Creator() {
            public Experiment createFromParcel(Parcel in) {
                return new Experiment(in);
            }

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


}

The Measurements Class

package nl.bioinf.thema12.labpal.objects;

import java.util.ArrayList;

import android.os.Bundle;
import android.os.Parcel;
import android.os.Parcelable;
/**
 * @author roy
 * a class which describes a group of measurements
 */

public class Measurements implements Parcelable{
    private ArrayList<Double> measurements;
    private String measurementName;

    //each measurement has at least a name and an empty list of measurements
    public Measurements(String measurementName) {
        this.measurementName=measurementName;
        measurements = new ArrayList<Double>();
    }

    /**
     * a method which adds a measurement to an ArrayList of measurements
     * @param   measurement a measurement to add to the ArrayList
     */
    public void addMeasurement(double measurement){
        measurements.add(measurement);
        System.out.println("added a measurement");
    }

    /**
     * a method which returns the measurement name
     * @return  the measurement name
     */
    public String getMeasurementName(){
        return measurementName;
    }

    /**
     * a method which returns an ArrayList of the values in the measurement
     * @return  the values of the measurements in an ArrayList
     */
    public ArrayList<Double> getMeasurements(){
        return measurements;
    }

    //This makes the object parselable, I don't understand why
    /**
     * a constructor for the parcelable variant of the object
     */     
    public Measurements(Parcel in){
        measurements = new ArrayList<Double>();
        readFromParcel(in);

    }

    @Override
    public int describeContents() {
        // TODO Auto-generated method stub
        return 0;
    }

    /**
     * a method which writes the objects to a parcel
     */ 
    @Override
    public void writeToParcel(Parcel dest, int flags) {
        //dest.writeString(measurementName);
        //dest.writeList(measurements);
        Bundle b = new Bundle();
        b.putString("measurementName", measurementName);
        b.putSerializable("measurements", measurements);
    }

    /**
     * a method which reads from a parcel
     */ 
    public void readFromParcel(Parcel in){
        //measurementName = in.readString();
        //measurements = in.readArrayList(Object.class.getClassLoader());
        Bundle b = in.readBundle();
        measurementName = b.getString("measurementName");
        measurements = (ArrayList<Double>)b.getSerializable("measurements");
    }

    /**
     * generic parcelable creator method
     */ 
    public static final Parcelable.Creator CREATOR =
        new Parcelable.Creator() {
            public Measurements createFromParcel(Parcel in) {
                return new Measurements(in);
            }

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

code for the activity that receives the bundle

protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    //get the intent passed by the other activity
    Bundle b = getIntent().getExtras();
    experiment = b.getParcelable("nl.bioinf.thema12.labpal.objects.Experiment");
    setContentView(R.layout.activity_show_table);
}

code for the activity that sends the bundle

//setup the table button
        table = (Button)findViewById(R.id.button_activityMain_table);
        table.setOnClickListener(new OnClickListener(){
            @Override
            public void onClick(View v){
                try{
                    Intent intentToPassToShowTable = new Intent(MainActivity.this, ShowTable.class);
                    Bundle b = new Bundle();
                    b.putParcelable("nl.bioinf.thema12.labpal.objects.Experiment", experiments.get(experimentName.getSelectedItem().toString()));
                    intentToPassToShowTable.putExtras(b);
                    startActivity(intentToPassToShowTable);
                }
                catch(Exception e){
                    e.printStackTrace();
                }
            }
        });
Was it helpful?

Solution

Hi There Try this code it's working fine

  package com.example.objectsharing;

import java.util.ArrayList;
 import java.util.HashMap;

import android.os.Bundle;
import android.os.Parcel;
import android.os.Parcelable;

public class Experiment implements Parcelable {
private String experimentName = "";
private HashMap<String, ArrayList<Double>> measurements = new HashMap<String, ArrayList<Double>>();

// every Experiment needs a name to make it unique
public Experiment(String experimentName) {
    this.experimentName = experimentName;
}

/**
 * a method which adds values to a measurement
 * 
 * @param measurementName
 *            the name of the measurement you want to write a value to
 * @param measurement
 *            the value of the measurement you want to add
 * @return the sequence from the fasta
 */
public void addValueToMeasurements(String measurementName,
        double measurement) {
    // try to add the measurement
    if (measurements.get(measurementName) == null) {
        // Measurements m = new Measurements(measurementName);
        ArrayList<Double> _data = new ArrayList<Double>();
        // m.addMeasurement(measurement);
        _data.add(measurement);
        measurements.put(measurementName, _data);
    }
    // if the measurement does not exist, create it
    else {
        measurements.get(measurementName).add(measurement);
    }
}

/**
 * a method which returns the experiment name
 * 
 * @return the experiment name
 */
public String getExperimentName() {
    return experimentName;
}

// This makes the object parselable, I don't understand why
/**
 * a constructor for the parcelable variant of the object
 */
public Experiment(Parcel in) {
    measurements = new HashMap<String, ArrayList<Double>>();
    readFromParcel(in);
}

@Override
public int describeContents() {
    // TODO Auto-generated method stub
    return 0;
}

@Override
/**
 * a method which writes the objects to a parcel
 */
public void writeToParcel(Parcel dest, int flags) {
    // dest.writeString(experimentName);
    // for(String s: (Set<String>)measurements.keySet()){
    // dest.writeString(s);
    // dest.writeValue(measurements.get(s));
    // }
    Bundle b = new Bundle();
    b.putString("experimentName", experimentName);
    b.putSerializable("measurements", measurements);
    dest.writeBundle(b);
}

/**
 * a method which reads from a parcel
 */
public void readFromParcel(Parcel in) {
    // experimentName = in.readString();
    Bundle b = in.readBundle();
    experimentName = b.getString("experimentName");
    measurements = (HashMap<String, ArrayList<Double>>) b
            .getSerializable("measurements");
}

/**
 * generic parcelable creator method
 */
public static final Parcelable.Creator CREATOR = new Parcelable.Creator() {
    public Experiment createFromParcel(Parcel in) {
        return new Experiment(in);
    }

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

}

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top