Комментарии 26
github.com/greenrobot/EventBus
2. альтернативное решение из коробки для передачи сообщения от одной части к другой?
я не адвокат greenrobot, но они в индустрии уже давно, уже в 2016 их многие библиотеки считались золотым стандартом.
После того, как прочухал и отстрада п.1 выше, в своих проектах на любых платформах стараюсь воздерживаться от дополнительных источников и приемников event, предпочитаю выстраивать архитектуру с более ясной инфраструктурой данных
2. Rx или LiveData.
if (getActivity() != null && !getActivity().isFinishing()) {
((MainActivity) getActivity()).fragmentMail(counter);
}
В данном случае, контекст всегда будет у одной и той же активити, да и интерфейс никакой не нужен
При необходимости можно еще добавить проверку на класс
Все дела
Интерфейс – это, пожалуй, единственная здравая мысль в статье. Так что, если хочется простоты, то на котлине можно сделать так:
(activity as? Postman)?.fragmentMail(counter)
Или же сделать реализацию интерфейса обязательной, в зависимости от требований:
(activity as Postman).fragmentMail(counter)
Конечно, в этом случае, если активити-хозяин не реализует необходимый интерфейс, то приложение упадет.
А вот проверку на isFinishing
я бы во фрагменте не делал – это совсем не забота фрагмента следить за жизненным циклом активити. Если эта проверка нужна, то ее сама активити и должна делать.
А потом все дружно удивляются от куда у нас столько говнокодеров
2) Presenter? ViewModel?
3) можно и так, но врядли твои коллеги одобрят+при перевороте значение потеряется
Т.е. сразу так и написать if ( context is Postman) this.postman = context
Всегда делал так. Это даст больше универсальности, т.к. postman может приходить, например, не только из контекста, но и передаваться сообщением или через save/restore или ещё десятком способов. Фильтры там нагородить можно будет.
SomeShit.kt:
object SomeShit
{
var SomeCounter: Int = 0
}
после чего в фрагменте можно писать в SomeShit.SomeCounter, а в активности читать оттуда и наоборот. Чувствую что есть какой то подвох, потому что слишком просто получается но не могу придумать какой именно.
На самом деле примерно так и надо (ну не именно так, а чуть хитрее). Я вообще не понимаю, почему большинство примеров начинаются с хранения состояния в активити и попыток его сохранить/передать при повороте экрана, сворачивании приложения и переходе на другую активити.
Всей этой боли можно избежать, если сделать иначе: хранить состояние отдельно от активити в более стабильном месте: например, в статическом поле, в поле application, а что-то долговременное вообще сохранять в preferences.
Есть некоторые моменты, связанные с многопоточностью и activity lifecycle (оно может создаваться заново, поэтому ссылку на него хранить нельзя, но при этом его надо как-то уведомлять об изменения состояния). В androidx появились стандартные классы, которые делают это адекватным образом:
- Класс для хранения состояния, который может уведомлять подписавшихся, причем состояние можно изменять и из UI потока, и из другого.
- У activity появился lifecycleOwner, благодаря чему активити при завершении работы будет отписано от уведомлений.
Я не использовал этот подход для чего-то сложного, но на простых примерах очень понравилось — код намного проще и короче.
Подвох в том, что это, по сути, глобальная переменная, со всеми вытекающими: отсутствие инкапсуляции, нерасширяемость в результате невозможности иметь более одного независимого экземпляра класса и т.д.
fun setPostman(postman: Postman) {
this.postman = postman
}
и из активности вызвать fragment.setPostman(this)
Не говорю, что это единственное и лучшее решение, но если речь о передаче данных через интерфейс, то стоит делать так, иначе джуны рискуют нарваться как минимум на критику ментора
Как в Android'е передать переменную из фрагмента в активность?