【问题标题】:How would I correctly implement parcel/parcelable in a Hash of objects in Java/Android我将如何在 Java/Android 中的对象哈希中正确实现 parcel/parcelable
【发布时间】:2013-05-17 09:35:29
【问题描述】:

我有以下课程:实验和测量。我在 Android 活动之间传递一个包含 Experiment 对象的 HashMap 作为值,并将它们的 Experiment.getExperimentName 作为键。

这些 Experiment 对象又包含一个 Measurements 对象的 HashMap。这个 HashMap 有一个 Measurements 对象作为值,它们的 Measurements.getMeasurements 作为键。

这些 Measurements 对象随后包含一个双精度数的 ArrayList。

我尝试了许多使用捆绑包或直接放入包裹的变体,但是当我在新活动中读取 HashMap 时,我不断收到“解组时出现 ClassNotFoundException:nl.bioinf.thema12.labpal.objects.Measurements” .

如何正确实现 parcel/parcelable?

实验课:

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];
            }
     };


}

测量类

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];
            }
     };
}

接收包的活动代码

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);
}

发送包的活动代码

//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();
                }
            }
        });

【问题讨论】:

    标签: android object hash hashmap parcel


    【解决方案1】:

    你好试试这个代码它工作正常

      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];
        }
    };
    

    }

    【讨论】:

    • 这给了我 Experiment.writeToParcel 中的以下错误:“Bundle 类型中的 putParcelable(String, Parcelable) 方法不适用于参数 (String, HashMap)”
    • 请检查修改后的答案是否正常。我认为这会对你有所帮助。
    • 我已经添加了在活动之间发送和接收捆绑包的方法,那里有什么问题吗?
    • 错误的Measurement类没有用parceable实现,你没有写这两者,这就是它给出坏parcel Object异常的原因。现在它应该可以尝试
    猜你喜欢
    • 2011-08-16
    • 2011-10-25
    • 2012-03-12
    • 2014-02-18
    • 1970-01-01
    • 1970-01-01
    • 2015-07-07
    • 1970-01-01
    • 2011-01-19
    相关资源
    最近更新 更多