2013-07-15 2 views
2

Я компьютерный хобби, который работает над очень маленькой мелочью для платформы Android.Как сохранить объекты данных в Android/Java?

В этой игре я перемещаю плеер между несколькими страницами активности/просмотра (запись, страница вопросов, страница ответов, страница с окончательной оценкой). Я создал объект вопроса, который содержит все данные, относящиеся к одному мелочам (вопрос, четыре ответа, указатель на правильный ответ, связанные комментарии, которые компьютер делает, отвечая на догадку игрока), и я успешно заполнил ArrayList объектов Question с данными, которые я DOM проанализировал из файла XML.

Что такое приемлемый способ передачи этих данных взад и вперед между действиями по мере продвижения игры? Как я могу сохранить эти объекты данных живыми, когда пользователь перемещается по игре?

Я понимаю, что глобальные переменные сильно обескуражены. Я также узнал, что шаблон проектирования Singleton создает многие проблемы, которые, как говорят, связаны с глобальными переменными. Я в тупике, когда дело доходит до поиска альтернатив этим подходам.

Я понимаю основы подхода MVC. Моя активность * .java-файлы - это файлы контроллера, и они связаны с макетами (представлениями), которые я создал с помощью XML. У меня есть два «модельных» объекта, которые необходимо поддерживать и модифицировать по ходу игры: (1) упомянутый выше вопрос-банк ArrayList и (2) какой-то объект «PlayerProgress», содержащий все данные, связанные с прогрессом игрока в игра.

Эти объекты данных сначала создаются в начале игры, но я не знаю, как сохранить их в живых, когда пользователь перемещается между действиями. Я знаю, что я могу передавать информацию между действиями как EXTRAS, но EXTRA, похоже, не предназначены для этой цели. Даже если EXTRAS работал на свойства прогресса игрока, я не думаю, что могу использовать их для передачи ArrayList из 25-50 объектов вопроса между действиями.

Я изучил сериализацию и разборчивость, но кажется странным (и, возможно, неэффективным) в основном разлагать, а затем перекомпоновать объекты модели данных каждый раз, когда пользователь перемещается вперед и назад между различными видами деятельности/видами. Если один из них является приемлемым/общепринятым способом достижения этого, я могу с радостью окунуться вперёд, но сначала мне нужно было проверить с другими.

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

Я задаю этот вопрос («Что является приемлемым способом передачи объектов данных взад и вперед между действиями по мере продвижения игры») в контексте моей глупой игры с пустяками, но я действительно заинтересован в получении обрабатывать большую картинку. Если у людей нет времени, чтобы изложить что-то настолько, казалось бы, базовое, возможно, вы можете указать мне на описания в других книгах, которые вы нашли полезными? (У меня есть несколько слотов, открытых в книжной полке Safari, и вы можете найти копии практически любых технических публикаций.)

Спасибо.

+0

«Я не думаю, что могу использовать их, чтобы передать ArrayList из 25-50 объектов вопроса между действиями». - вы определенно можете, на самом деле, – invertigo

+0

invertigo, у меня создалось впечатление, что EXTRAS являются парами ключ/значение со значениями обычно String или int datatypes. Если одно значение EXTRA может содержать весь ArrayList из 25-50 объектов вопроса, это кажется идеальным. Я изучаю далее, чтобы убедиться, что я не совсем неправильно понял, что мы можем делать с дополнительными функциями. –

+0

вам придется оценивать влияние производительности для вашего собственного прецедента, но я использую serializable extra для хранения списка <> сериализуемых объектов все время – invertigo

ответ

2

У меня нет достаточного количества голосов, чтобы ответить прямо в сообщении 323go о статических переменных ... но эта реализация - это точно Синглтон. Я хотел бы указать на это, потому что вы заявили в своем вопросе, что вы также узнали, что шаблон проектирования Singleton создает многие проблемы, которые, как говорят, связаны с глобальными переменными.

Я признаю, что дополнительные функции довольно странные в первый раз, если вы привыкли вызывать функцию или программу со своими параметрами в ряд, но, похоже, это обычный способ в Android. Я не понимаю, в чем проблема с использованием дополнительных функций, так как это почти прозрачно для вас, если ваши объекты модели не очень сложны. Я имею в виду, вам просто нужно реализовать интерфейс «Serializable», и это сделано. Существуют некоторые типы данных, которые сами по себе не работают с Serializable (в виде списков), и вам нужно будет реализовать Parcelable, но вы можете объявить массивы insted. Кажется, Parcelable является «гораздо более эффективным», так что если вы хотите лучше выполнять вам нужно в любом случае для реализации Parcelable, как кто-то здесь сказал: Android: Difference between Parcelable and Serializable?

Я не думаю Общие предпочтения предназначены для использования в качестве «инструмент передачи аргументов», поскольку он не будет настолько эффективным, как он должен писать и читать в физическую память, что должно быть «трудным» в любой компьютерной системе; в то время как exras будет отправлен через стек памяти (Disclaimer: я не тестировал, но это то, что говорит мне логика). Я использую способ dannyroa (хранение объектов json) для сохраняющихся во времени проблем в качестве пользовательских предпочтений, загруженных из Интернета малоинформационных данных, оценок, savegames ....

И, наконец ... возможно, вы можете перестроить свой код , Вы открываете новую деятельность для каждого вопроса? Возможно, вы можете использовать только одно действие и использовать фрагменты. Затем вы можете иметь свою глобальную переменную в активности, и любой фрагмент внутри может туда попасть с getActivity().

((MyActivity)getActivity()).myGlobalVariable(); 
+0

Спасибо, Эндер. Я понял, что глобальный статический объект - это точно Singleton. Я использую PREFERENCES только для хранения одного или двух бит по-настоящему постоянной информации об общем состоянии пользователя. Я копаю обратно в последовательный, сериализуемый через ваши ссылки. Я, очевидно, должен лучше разбираться в EXTRAS. // У меня теперь есть только один вопрос «Активность», и я использую флиппер вида, чтобы прыгать назад и вперед между вопросом и результатом. Это решило большую часть проблемы, которая вызвала оригинальный пост. Предложение фрагментов похоже на аналогичное решение. Благодаря! –

+0

Привет Эндер, Просто хотел проследить и подтвердить мудрость вашей рекомендации, что я должен использовать фрагменты. Я переписываю вторую версию игры с фрагментами, и она полностью решает мою проблему именно по причинам, которые вы упомянули. –

0

Что я пытаюсь сохранить в SharedPreferences.

Чтобы сохранить объекты, я использую библиотеку Gson для преобразования ее в строку JSON & конвертировать строку JSON обратно в объект.

Однако это означает, что он будет работать только для объектов Serializable. & есть накладные расходы при чтении и записи из SharedPreferences.

Идеальное решение представляет собой комбинацию глобальных статических & SharedPreferences. В случае, если статическая переменная равна null, получите ее из SharedPreferences. Обязательно очистите статическую переменную, когда значение в SharedPreferences будет обновлено.

static String userInfo = null; 
public static String getUserInfo() { 
    if (userInfo != null) { 
     return userInfo; 
    } 
    return _getStringFromPref("userInfo"); 
} 

public static String setUserInfo(String val) { 
    _putStringToPref("userInfo", val); 
    userInfo = val; //or you can just set userInfo to null; 
} 

Вы также можете использовать локальную базу данных (sqlite) вместо SharedPreferences.

+0

Спасибо, Дэннироа. Я собираюсь дать «статический глобальный» подход. Будет округлен с обновлением в разделе комментариев. –

+0

Aaron: Я пробовал статический глобальный, но проблема в том, что когда ваше приложение перемещается в фоновом режиме, вы не можете гарантировать, что значение будет там. Если Android необходимо освободить память, они очистят память, выделенную приложениям в фоновом режиме. – dannyroa

+0

Хм. Я понимаю, что вы говорите, dannyroa. Что, если я должен был объединить два решения? Интересно, могу ли я переопределить метод, связанный с приложением, перемещающимся на задний план. В эти моменты я бы использовал библиотеку GSON, чтобы преобразовать ее в строку JSON. В противном случае, когда вы просто двигаетесь назад и вперед между действиями, я бы использовал статический глобальный. // Но это будет работать только в том случае, если я буду уверен, что всегда буду записывать это событие вовремя. –

1

В Intent Extras вы можете поместить массив добавочных объектов, чтобы можно было отправлять массив объектов вопросов между действиями.

Лично я бы использовал базу данных sqlite для хранения вопросов и вытащил их из БД через поставщика контента.

Может быть излишним для вашего приложения в настоящее время, но если вы когда-либо расширяете вопрос, вы можете изменить SQL, чтобы вытащить соответствующее подмножество вопросов для каждого вида деятельности.

+0

Спасибо, jsr. Я собираюсь экспериментировать с этим подходом. –

0

В моем первоначальном посте я пообещал вернуться назад после изучения всех вариантов.

Просто хотел сообщить, что самым простым решением, как предлагает Эндер, является использование нескольких фрагментов и одной страницы активности.Это позволяет полностью избежать глобальных статических объектов, поскольку все фрагменты могут получить доступ к классу MainActivity.

Смежные вопросы