Reputation: 3
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();
}
}
});
Upvotes: 0
Views: 2564
Reputation: 1477
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];
}
};
}
Upvotes: 1