22

シリアライズ可能な Java Bean オブジェクトがあるとします。アクティビティが意図的に onDestroy()を通過するとき(つまり、onSaveInstanceState() が呼び出されないとき) に、安全に保管したいと考えています。

私は、データベースを作成してそれにオブジェクトを書き込むことを伴わない方法を探しています (主に、a) Android の DB API は恐ろしいものであり、b) データベースはアプリケーションの更新を悪夢にするため、移行を適用するための適切なサポートがないためです。 )。

オブジェクトを ByteArrayOutputStream にシリアル化し、それを base64 エンコードして、SharedPreferences ファイルに文字列として書き込むことを考えました。それとも、それは遠すぎますか?

アップデート

おそらく、文字列へのシリアル化のアイデアはそれほど悪くはなかったのですが、かなりうまく機能しているようです。これが私が今していることです:

    public static String objectToString(Serializable object) {
    ByteArrayOutputStream out = new ByteArrayOutputStream();
    try {
        new ObjectOutputStream(out).writeObject(object);
        byte[] data = out.toByteArray();
        out.close();

        out = new ByteArrayOutputStream();
        Base64OutputStream b64 = new Base64OutputStream(out);
        b64.write(data);
        b64.close();
        out.close();

        return new String(out.toByteArray());
    } catch (IOException e) {
        e.printStackTrace();
    }
    return null;
}

public static Object stringToObject(String encodedObject) {
    try {
        return new ObjectInputStream(new Base64InputStream(
                new ByteArrayInputStream(encodedObject.getBytes()))).readObject();
    } catch (Exception e) {
        e.printStackTrace();
    }
    return null;
}

onDestroy() では、Base64 文字列を環境設定ファイルに書き込むだけで済みます。このファイルは、次のアクティビティの起動時に再度読み取るまで安全です。予想よりもはるかに高速で、Bean が大量のデータを保持しない限り、かなりうまく機能します。さらに良いことに、DB スキーマを維持する必要はありません。

それでも、私は他の人がこれをどのように行うかについて興味があります。

4

2 に答える 2

9

私は、データベースを作成してそれにオブジェクトを書き込むことを伴わない方法を探しています (主に、a) Android の DB API は恐ろしいものであり、b) データベースはアプリケーションの更新を悪夢にするため、移行を適用するための適切なサポートがないためです。 )。

Android の API は、実際にはかなり合理的です。これは主に、SQLite API のシン ラッパーであるためです。また、SQLite API は組み込みデータベースに対してもかなり合理的です。さらに、Android はアプリのアップグレード時にスキーマのアップグレードを支援しますSQLiteOpenHelper

予想よりもはるかに高速で、Bean が大量のデータを保持しない限り、かなりうまく機能します。

シリアライゼーションで長期的な成功を収めている人たちよりも、シリアライゼーションから逃げ出している開発者の方がはるかに多いと聞いています。ここ数日の間に、ここ SO #android で、アプリからシリアライゼーションを根こそぎ剥ぎ取ろうと必死に試みている誰かとやり取りがありました。

さらに良いことに、DB スキーマを維持する必要はありません。

ああ、そうです。アプリケーションを更新してクラスが変更されるとどうなると思いますか? 新しいバージョンのクラスから古いバージョンのクラスを逆シリアル化する方法を把握するために簿記を行うのは雑用であり、開発者がシリアル化を放棄する理由の 1 つです。また、シリアライゼーションはトランザクションに対応していませんが、SQLite はトランザクションに対応していることを忘れないでください。

于 2009-10-28T14:09:04.717 に答える
3

また、Bean やアクティビティの状態を un/marshalling するための優れたアプローチも探していました。アクティビティの onStoreInstanceState() と onRestoreInstanceState() がどれほど面倒かは誰もが知っています。

私の活動は、単純にその状態を onPause() に保存し、オブジェクトの直接シリアル化を介して onCreate() ライフサイクル フックに復元します。

あなたのように文字列を介したシリアル化はもちろん可能ですが、大きなデータにはあまり適しておらず、多くのオーバーヘッドが発生します。さらに、設定は実際にはデータではなく設定を保存するためにあります:) 残念ながら、この目的で使用できる Parcelable / Parcel は、永続的なストレージに保存することをお勧めしません。

したがって、残っているのは単純なオブジェクトのシリアル化です。幸いなことに、Android SDK には ObjectInputStream および ObjectOutputStream クラスの実装があり、すべての欠点と利点があります。これは、Android 以外の Java の世界でも行うように、単純です。

ObjectOutputStream.writeObject(yourPojo)

(Serializable マーカー インターフェイスを実装することを忘れないでください)

また、コンテキスト - ContextWrapper - アクティビティの次の API を調べることもできます。これは、ローカル データ (画像など) などをキャッシュするのに非常に役立ちます。

.getCacheDir()
.getDir()
.openFileInput()
.openFileOutput()

ハッピーハッキング:)

于 2013-02-16T14:56:04.850 に答える