2

GeoPoints のリストをシリアライズしてから、再度読み込む必要があります。Web を検索したところ、独自の GeoPoint を実装してシリアライズ可能に実装できることがわかりました。それは機能し、オブジェクトを.serファイルに書き込むことができますが、それを読み返すと、無効なクラス例外が発生し、詳細メッセージが表示されます-元のGeoPointオブジェクトの不正アクセス例外. MyGeoPoint クラスで GeoPoint を適切に拡張していないと思います。誰かが見て、私がどこでエラーを起こしているのか教えてもらえますか?

import com.google.android.maps.GeoPoint;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;

public class MyGeoPoint extends GeoPoint implements Serializable {
static final long serialVersionUID = -3010695769693014199L;


public MyGeoPoint(int latitude, int longitude){
    super(latitude, longitude);
}
public MyGeoPoint(){
    this(0,0);
}
private void writeObject(ObjectOutputStream s) throws IOException{
    s.defaultWriteObject();
}
private void readObject(ObjectInputStream s)
        throws java.io.IOException, java.lang.ClassNotFoundException{
    s.defaultReadObject();
}
}

そして、それは次のように使用されます

File filex = new File(Environment.getExternalStorageDirectory().getAbsolutePath() + File.separator +"floodData.ser");
    MyGeoPoint aPoint = new MyGeoPoint();
    MyGeoPoint readPoint = null;
    //write
    try{
    FileOutputStream f = new FileOutputStream(filex);
    ObjectOutputStream s = new ObjectOutputStream(f);
    s.writeObject(aPoint);
    s.close();
    } catch (IOException e) {
        e.printStackTrace();
    }

    //read
    try {
    FileInputStream ff = new FileInputStream(filex);
    ObjectInputStream ss = new ObjectInputStream(ff);
    readPoint = (MyGeoPoint)ss.readObject();
    ss.close();
    } catch (ClassNotFoundException e) {
        e.printStackTrace();
    } 
    catch (Exception e) {
        e.printStackTrace();
    } 
    //end serialisationtest 
4

4 に答える 4

4

問題は、GeoPoint引数なしのコンストラクターがないことです。Serializableの JavaDoc を参照してください。

シリアル化できないクラスのサブタイプをシリアル化できるようにするために、サブタイプは、スーパータイプの public フィールド、protected フィールド、および (アクセス可能な場合) package フィールドの状態を保存および復元する責任を負う場合があります。サブタイプは、それが拡張するクラスに、クラスの状態を初期化するためのアクセス可能な引数なしのコンストラクターがある場合にのみ、この責任を負うことができます。そうでない場合、Serializable クラスを宣言するとエラーになります。エラーは実行時に検出されます。

そして、InvalidClassExceptionの JavaDoc

シリアライゼーション ランタイムがクラスで次のいずれかの問題を検出した場合にスローされます。

  • クラスのシリアル バージョンが、ストリームから読み取ったクラス記述子のシリアル バージョンと一致しません
  • クラスに不明なデータ型が含まれています
  • クラスには、アクセス可能な引数なしのコンストラクターがありません
于 2012-01-11T10:18:05.237 に答える
1

com.google.android.maps.GeoPointを拡張して、緯度/経度座標を格納するためのシリアル化可能なオブジェクトを作成する必要はありません。

また、元のオブジェクトを所有していないため、元のGeoPointを変更することを決定した場合、たとえば、メソッドの追加/削除、メソッドの署名の変更などを行うと、問題が発生する可能性があるため、所有しないでください。

さらに悪いことに、コードは移植性がなく、KindleFire上のFYIAndroidはGoogleMaps APIにアクセスできないため、com.google.android.maps.GeoPointから拡張されたアプリは機能しません。

実行する方法は、同じ正確なプロパティ(およびそのタイプ)を使用してシリアル化可能なPOJOを作成し、シリアル化する緯度/経度座標を格納することです。

package com.yourapp.beans;

public class YourGeoPoint implements Serializable {

        private static final long serialVersionUID = -99127398709809L;

        private int latitudeE6;
        private int longitudeE6;

        public YourGeoPoint() {
            this.setLatitudeE6(0);
            this.setLongitudeE6(0);
        }

        public YourGeoPoint(int latitudeE6, int longitudeE6) {
            this.setLatitudeE6(latitudeE6);
            this.setLongitudeE6(longitudeE6);
        }

        public int getLatitudeE6() {
            return latitudeE6;
        }

        public void setLatitudeE6(int latitudeE6) {
            this.latitudeE6 = latitudeE6;
        }

        public int getLongitudeE6() {
            return longitudeE6;
        }

        public void setLongitudeE6(int longitudeE6) {
            this.longitudeE6 = longitudeE6;
        }

    }

次に、 com.google.android.maps.GeoPoint ...が必要なときはいつでも、yourGeoPointインスタンスに逆シリアル化した後、次のようにします。

import com.google.android.maps.GeoPoint;
import com.yourapp.beans.YourGeoPoint;
//...    
YouGeoPoint yourGeoPoint = // De-serialization...        
GeoPoint geoPoint = new GeoPoint(yourGeoPoint.getLatitudeE6(), yourGeoPoint.getLongitudeE6());

100%動作し、コードはGoogle Maps APIが存在しないAndroidデバイスに移植できます...その場合は、アクセスできるマップライブラリ(ESRIやOpenSignalMapsなど)をインポートして取得してくださいそれらの「GeoPoints」または同等のオブジェクトの、独自の逆シリアル化されたオブジェクトからの座標を使用します。

乾杯!

于 2012-11-10T02:00:48.377 に答える
0

この回答をより完全にするために、応急処置で問題を解決しようとしました。次の行をクラス writeObject および readObject に追加してみてください...

private void writeObject(ObjectOutputStream s) throws IOException{
    s.writeInt(this.getLatitudeE6());
    s.writeInt(this.getLongitudeE6());
}
private void readObject(ObjectInputStream s)
        throws java.io.IOException, java.lang.ClassNotFoundException{
    this(s.readInt(), s.readInt());
}
于 2012-08-08T05:45:13.510 に答える