Подтвердить что ты не робот

Как сохранить сложный объект во время перезагрузки Activity?

Скажем, у меня есть объект Java Bean, который является сериализуемым. Я хочу сохранить его безопасно, когда действие проходит через onDestroy() специально (т.е. OnSaveInstanceState() не вызывается).

Я ищу способ, который не связан с созданием базы данных и написанием объекта для этого (в основном, поскольку а) API БД Android ужасен и б), поскольку базы данных делают обновления приложений кошмаром, потому что нет достойной поддержки для применения миграции).

Я думал о сериализации объекта в ByteArrayOutputStream, base64 encode и записывал его в файл SharedPreferences в виде строки. Или это слишком далеко?

UPDATE

Может быть, идея с сериализованной строкой в ​​конце концов не так уж плоха, похоже, очень хорошо работает. Вот что я делаю сейчас:

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

in onDestroy() Затем я могу просто написать строку Base64 в файл предпочтений, где он безопасен, пока я не прочитаю его снова во время следующего запуска активности. Это намного быстрее, чем я ожидал, и если ваш beans не несет огромных объемов данных, он работает очень хорошо. И даже лучше, вам не нужно поддерживать схему БД.

Тем не менее, мне интересно, как это делают другие.

4b9b3361

Ответ 1

Я ищу способ, который не включать создание базы данных и запись объект к этому (в основном, поскольку a) API БД Android ужасен и b) поскольку базы данных делают заявку обновляет кошмар, потому что есть нет достойной поддержки для применения миграции).

Android API на самом деле довольно разумен, главным образом потому, что он представляет собой тонкую оболочку над SQLite API, а SQLite API достаточно разумен для встроенной базы данных. Кроме того, Android предоставляет помощь для обновления схем при обновлении приложений, через SQLiteOpenHelper.

Это намного быстрее, чем я ожидал и если ваш beans не несет огромные суммы данных, он работает очень хорошо.

Я слышал о том, что многие разработчики убегают от сериализации, чем я слышал о людях, имеющих долгосрочный успех. Только за последние несколько дней, здесь, на SO #android, у меня был обмен с кем-то, кто отчаянно пытался сорвать сериализацию из своего приложения корнями.

И даже лучше, вам не нужно поддерживать схему DB.

О да, да. Как вы думаете, что произойдет, когда вы обновите приложение и измените свой класс? Выполнение бухгалтерского учета, чтобы выяснить, как десериализовать старые версии класса из новой версии класса, является основной задачей и является одной из причин, по которым разработчики отказаться от сериализации. Кроме того, не забывайте, что сериализация не является транзакционной, тогда как SQLite - это.

Ответ 2

Я также искал хороший подход un/marshalling любых beans или состояний активности. Мы все знаем, насколько активна активность onStoreInstanceState() и onRestoreInstanceState().

Мои действия просто сохраняют свои состояния в onPause() и восстанавливают их в onCreate() привязках жизненного цикла через сериализацию прямого объекта.

Сериализация через String, как и вы, конечно, возможна, но менее подходит для больших данных и вызывает много накладных расходов. Кроме того, предпочтения на самом деле существуют для хранения предпочтений, а не данных. К сожалению, Parcelable/Parcel, что мы могли бы использовать для этой цели, не рекомендуется хранить в постоянном хранилище.

Итак, оставшаяся часть - это простая сериализация объектов. К счастью, у Android SDK есть реализация классов ObjectInputStream и ObjectOutputStream со всеми недостатками и преимуществами - как мы бы это сделали и в мире Java, отличном от android, простой:

ObjectOutputStream.writeObject(yourPojo)

сделает магию для нас (не забудьте реализовать интерфейс Serializable-marker)

Кроме того, вы можете посмотреть в следующих API-интерфейсах контекста - ContextWrapper - Activity, которые очень полезны для кеширования локальных данных (например, изображений) и т.д.:

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

счастливый взлом:)