0

I am trying to pass a collection of custom objects to a service in android.

try {
    FileParser parser = new FileParserImpl();
    Collection<SensorReading<Long, Float>> collection = parser.parse(fileContents);
    Intent intent = new Intent(FileBrowserActivity.this, DataService.class);

    intent.putExtra(PARAM_SENSOR_DATA, (Serializable)collection);  //exception here.
    startService(intent);
catch (Exception e) {   //e = null, 
    Log.e(TAG, "We go an exception", e);
}

I get the exception at line marked in the code and the corresponding catch block gets the value as null. To get the message I do a force step into at the line where I get exception and it take me to the class ClassCastException where I see this message in debug mode : java.util.hashmap$values cannot be cast to java.io.serializable. I followed the suggestion given here

Also passing the object as intent.putExtra(PARAM_SENSOR_DATA, collection) gives compilation error with message that cannot resolve method

SensorReading is an interface as shown below:

public interface SensorReading<X, Y> {
    String getSensorIdentifier();
    List<Pair<X, Y>> getReadings();
    void addReading(Pair<X, Y> reading);
}

and SensorReadings is the implementation:

public class SensorReadings implements SensorReading<Long, Float>, Serializable {
    private static final long serialVersionUID = -2518143671167959230L;
    String location;
    String sensorName;

    public SensorReadings(String location, String sensorName) {
        //constructor
    }

    List<Pair<Long, Float>> timeStampReadingTuple;

    public void addReading(Pair<Long, Float> pair) {
        timeStampReadingTuple.add(pair);
    }

    public List<Pair<Long, Float>> getReadings() {
        return timeStampReadingTuple;
    }

    @Override
    public String getSensorIdentifier() {
        return sensorName + "@ " + location;
    }

    private void readObject(java.io.ObjectInputStream in) throws IOException, ClassNotFoundException {
        in.defaultReadObject();
        location = (String) in.readObject();
        sensorName = (String) in.readObject();
        int size = (int) in.readObject();
        timeStampReadingTuple = Lists.newArrayListWithCapacity(size);
        for(int i=0; i<size; ++i) {
            long timeStamp = (long) in.readObject();
            float reading = (float) in.readObject();
            timeStampReadingTuple.add(new Pair<Long, Float>(timeStamp, reading));
        }
    }

    private void writeObject(java.io.ObjectOutputStream out) throws IOException {
        out.defaultWriteObject();
        out.writeObject(location);
        out.writeObject(sensorName);
        out.writeObject(timeStampReadingTuple.size());
        for(Pair<Long, Float> pair : timeStampReadingTuple) {
            out.writeObject(pair.first);
            out.writeObject(pair.second);
        }
    }
}
Community
  • 1
  • 1
Aman Deep Gautam
  • 8,091
  • 21
  • 74
  • 130
  • can you post the complete stacktrace ? – Blackbelt Oct 13 '15 at 18:22
  • @Blackbelt In-line edited the question. Please see the area regarding the error message for edit. – Aman Deep Gautam Oct 13 '15 at 18:35
  • `Pair` is not serializable. Therefore anything containing a `Pair` is not serialitzable. `List> timeStampReadingTuple;` in your case if I'm not mistaken. http://developer.android.com/reference/android/util/Pair.html – zapl Oct 13 '15 at 18:52
  • @zapl I have implemented `readObject` and `writeObject` methods as well. Is that not correct? This is the firs time I am using serialization. – Aman Deep Gautam Oct 13 '15 at 18:54
  • Ooops, yes. I've just found that too :) Ignore my comment then. – zapl Oct 13 '15 at 18:55
  • I think you'll have to make `timeStampReadingTuple` `transient` (that's a keyword like `private`) because `defaultWriteObject` will otherwise try to write it. – zapl Oct 13 '15 at 19:00
  • @zapl is there a need of `defaultWriteObject`. I tested with and without it. Both versions do not work. Since I am writing everything, I think I do not need it, but have added it because the tutorial I was following had it. – Aman Deep Gautam Oct 13 '15 at 19:03
  • If you serialize everything yourself no. But you could let the default mechanism handle all fields that don't need special treatment and remove those parts from your code. – zapl Oct 13 '15 at 19:05

1 Answers1

1

I think the problem is that...

The ClassCastException is thrown to indicate that the code has attempted to cast an object to a subclass of which it is not an instance. You are trying to cast Collection to Serializable but Collection does not implement Serializable per se.

It the DataService (which is the service you want to start through your Intent) is an inner class you may want to store the collection in a temporary attribute of the parent class and use retrieve it within the service like

 ParentClass.this.collection
Andrea Sindico
  • 7,358
  • 6
  • 47
  • 84