Время жизни ViewModel при использовании требуемого Intent / Activity - PullRequest
0 голосов
/ 23 мая 2019

Проблема: моя ViewModel уничтожается, потому что я должен начать другую активность, пока она еще нужна(Это неизбежно новая (предоставляемая Android) активность.)

Справочная информация: у меня есть приложение, которое управляет взаимодействием между несколькими наборами данных.Он использует ViewModel в качестве кеша производительности, поскольку доступ к данным может быть медленным (например, за 10 секунд).В ViewModel не хранятся критические данные, но производительность была бы неприемлемой без кеша.Исходные данные находятся в файловой системе.

ViewModel работает точно так же, как и ожидалось, если я не проведу агрессивное тестирование и не включу опцию разработчика "Не сохранять действия" в качестве способа имитации нехватки памяти.По большому количеству логов я вполне уверен, что происходит (подробности ниже).У меня вопрос, если мне не хватает альтернативы тем, о которых я думал.

Сценарий:

  1. Приложение запускается и загружает ViewModel и запускает действие A. (AppCompatActivity toбыть точным.)
  2. Пользователь взаимодействует и решает изменить каталог, содержащий некоторые (не все) из кэшированных данных.Для этого требуется запустить встроенную в Android активность (D) «для результата» (чтобы получить новое имя каталога).Код для этого ниже.
  3. Если «Не сохранять действия» установлено , а не : выбор каталога работает нормально, а ViewModel выживает.(Эквивалентно: действие не уничтожено.)
  4. Если установлено «Не сохранять действия» (или система решает прекратить действие, пока пользователь находит новый каталог): Деятельность A уничтожается сразу после завершения новой операции (D) onCreate, и вызывается onCleared ViewModel.

(Это тестирование на Oreo, но я сомневаюсь, что это имеет значение.)

Вот намерение, которое начинает новую деятельность.По-видимому, это стандартный способ поиска файла или каталога, и он отлично работает (вместе с onActivityResult), чтобы получить новый каталог.

    Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT_TREE);
    intent.putExtra("android.content.extra.SHOW_ADVANCED",true);
    startActivityForResult(intent, REQUEST_DIR_LOOKUP);

Я экспериментировал с другим действием (назовите его B)где у меня есть код, который имеет ту же проблему, и не могу найти способ предотвратить очистку ViewModel в (4) выше.В случае поиска по каталогу (D) это даже не вариант изменить его.Это должно быть что-то, прежде чем начать поиск в каталоге.

В своей собственной Деятельности (B) я пытался использовать isFinishing() в ViewModel's onDestroy(), чтобы пропустить super.onDestroy, с неудивительным результатом, что система выдает ошибку, super.onDestroy()не звонил.Я также пытался заставить B onCreate получить ViewModel от A (успешно, это тот же адрес), но A onCleared все еще вызывается сразу после завершения B onCreate (я надеялся на счетчик ссылок).(Это подтверждается сообщениями журнала.)

Я не вижу способа предотвратить разрушение ViewModel при уничтожении A в случае 4 выше.Исправить это было бы идеальным решением.Преобразование ViewModel в классический синглтон должно работать.Если не сказать «не делай этого» «Не занимайся делами», это мой лучший выбор?

Если я пойду с синглтоном, есть ли лучший способ увидеть onClearedсобытие (когда я хочу уничтожить ViewModel), чем хак с использованием фиктивной ViewModel.onDestroy слишком рано, чтобы быть полезным.

Неделей позже

Комментарии, хотя и полезны, на самом деле не решают основную проблему, которая "законсервирована""Действия не играют хорошо с ViewModel.Я надеялся, что я что-то пропустил, но, видимо, нет, и мне придется обойти то, что мне кажется ошибкой в ​​дизайне.

Я думаю, что вижу несколько другую, детальную, но связанную проблему на Pie: «законсервированное» действие не учитывает текущее вращение (как это было во всех предыдущих версиях) (да, то же самоеактивность, как в примере кода).Это легко исправить в Activity, но требует его изменения, чего я стараюсь избегать, особенно для этого Activity, поскольку оно может меняться от релиза к релизу.

...