Передача обьекта в Activity

от
Android

Иногда возникает такая ситуация, что перед вызовом второй Activity нужно сначала передать туда какой-то обьект, без которого вторая Activity не может работать. У меня в первой активности отображается список уровней игры. Уровень представляет собой класс, в котором хранится InputStream, через который читается сначала название, размер уровня, а при выборе подгружается карта и другие данные. Поэтому второй активности, которая реализует игровой процесс, нужно как-то получить этот уровень.

           Способ 1, простой
     Проще всего во второй активности создать статический метод и обьекты, например:

Код первой
  1. // Когда выбрали нужный уровень
  2. GameActivity.preInit(levels.get(n));
  3. Intent i = new Intent(ctx, GameActivity.class);
  4. startActivityForResult(i, 0);

Вторая:
  1. static Level level;
  2. public static void init(Level l) {
  3.         level = l;
  4. }
  5.  
  6. @Override
  7. protected void onCreate(Bundle savedInstanceState) {
  8.     super.onCreate(savedInstanceState);
  9.     // отображаем уровень игры
  10. }

Недостатки: нужно все время помнить о необходимости вызова метода первоначальной инициализации, обьект должен быть статичным, код получается непонятным и запутанным.

Второй способ, сложный
     Можно использовать сериализацию, имплементировав интерфейс Serializable или Parcelable (говорят второй в разы быстрее), записывая и читая все поля обьекта для сохранения/восстановления соответственно. Нужно будет после любого изменения передаваемого обьекта, править его методы сериализации, к тому же, по сути, создаются новый обьект с тем самым содержанием, а не восстанавливается, поэтому меняется его адрес (ссылка) и состояние. Это приемлемо только для текстовых данных и примитивов.
      Для других случаев есть интерфейс IBinder. Он не используется напрямую, а используется его реализация Binder. Предназначен для взаимодействия разных элементов приложения (Service, Activity). Привожу реализацию вспомогательного класса, который позволяет передавать обьекты в одну строчку

Открыть спойлер

Пример использования:

Код первой Activity
  1. // Когда выбрали нужный уровень
  2. Intent i = new Intent(ctx, GameActivity.class);
  3. i.putExtra("level", new ParcelableBinder<Level>(levels.get(n)));
  4. startActivityForResult(i, 0);

Вторая:
  1. Level level;
  2.  
  3. @Override
  4. protected void onCreate(Bundle savedInstanceState) {
  5.     super.onCreate(savedInstanceState);
  6.     level = ((ParcelableBinder<Level>)getIntent().getParcelableExtra("level")).getObj();
  7.     // отображаем уровень игры
  8. }

Update
Собрал Android бибилиотеку на основе этого кода: parcelablebinder.aar
Положите ее в папку libs модуля проекта AndroidStudio, и в build.gradle проекта добавьте локальный репозиторий-папку:
  1. flatDir {
  2.     dirs 'libs'
  3. }
Пример получившегося файла:
Открыть спойлер

Теперь можно подключить библиотеку, по имени файла в скрипте build.gradle модуля:
  1. dependencies {
  2.     compile (name: 'parcelablebinder', ext: 'aar')
  3. }
Пример файла:
Открыть спойлер

Надеюсь код кому-нибудь пригодится. На этом все, удачи :gg:
  • +6
  • views 3494