2

Java サーバーと Android クライアントの間でオブジェクトのシリアル化ソケット接続を使用しようとしています。この接続を介して Calendar オブジェクトを送信しようとしたときに問題が発生しました。

Calendar オブジェクトは Java サーバーによって送信され、Android クライアントによって受信されますが、LogCat に次のエラー メッセージが表示されます。

java.lang.NullPointerException: タイプ java.util.TimeZone のレシーバーが必要でしたが、null を取得しました

ちゃんとデシリアライズしていないことに気づきました。

エラーを再現するために、次のコード サンプルを用意しました。

Java サーバー:

public class SerializeTest {

    public static void main(String[] args) {
        try {

        ServerSocket serverSocket = new ServerSocket(49100);
        Socket socket = serverSocket.accept();
        OutputStream oStream = socket.getOutputStream();
        ObjectOutputStream ooStream = new ObjectOutputStream(oStream);

        String testString = "This is a test String";
        Calendar testCalendar = Calendar.getInstance();

        ooStream.writeObject(testCalendar);
        ooStream.reset();
        ooStream.close();

        } catch(Exception e){
            e.printStackTrace();
        }
    }
}

Android クライアント: (空のプロジェクトを作成し、マニフェストにインターネット アクセス許可を追加しました)

public class MainActivity extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        Thread t = new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    Socket socket = new Socket("10.0.2.2", 49100);
                    InputStream iStream = socket.getInputStream();
                    ObjectInputStream oiStream = new ObjectInputStream(iStream);

                    Object object = oiStream.readObject();
                    Log.d("Test", object.toString());
                    oiStream.close();

                } catch (UnknownHostException e) {
                    e.printStackTrace();
                } catch (IOException e) {
                    e.printStackTrace();
                } catch (ClassNotFoundException e) {
                    e.printStackTrace();
                }
            }
        });
        t.start();
    }

}

そのコード サンプルを使用して、Java サーバーを起動し、Android エミュレーターで Android クライアントを実行すると、エラーが発生するはずです。

android-17/android.jar の java.util.Calendar オブジェクトが jre6 の java.util.Calendar オブジェクトと異なることに気付きました。ただし、どちらも 1807547505821590642L という同じ serialVersionUID を共有しています。(これは、シリアル化によって互換性を保つことを意図していたことを示しています)。

だから私はここで何が起こっているのかの説明を探していると思います.JavaとAndroidの両方でカレンダーオブジェクトの1つを使用できますか? (そうであれば、どのように?) 代わりに使用すべき別のオブジェクトはありますか?

4

2 に答える 2

3

Java サーバーと Android クライアントの間でオブジェクトのシリアライゼーション ソケット接続を使用しようとしています。

それがうまくいく可能性は低いです。

ちゃんとデシリアライズしていないことに気づきました。

これは、うまく機能しない理由の良い例です。Android は、バイナリ API の互換性を維持することに取り組んでいます。クラスの内部実装は変更される可能性があります。つまり、Java スタイルのオブジェクトのシリアライゼーションは変更される可能性があります。

Java と Android の両方でカレンダー オブジェクトの 1 つを使用できますか?

もちろん。異なるプラットフォーム間で Java スタイルのオブジェクトのシリアル化を使用しないでください。

long値を( )として渡すかgetTimeInMillis()、独自の JSON/XML/protobuf/シリアライザーを記述します。

于 2013-03-27T14:48:49.923 に答える
2

JavaSE バージョンと Android バージョンの間に 1 対 1 のマッピングはありません。Android と Java の進化は異なります。これらの SO の質問を参照してください。

serialVersionUIDこのため、Android を扱っていた人たちは、共通のクラスを変更することさえ気にしなかったと思います。シリアライゼーションの互換性は、ある JDK バージョンから別の JDK バージョンにクラスを進化させる際の最も賢明な問題の 1 つです。

于 2013-03-27T22:09:02.640 に答える