DEV_EASY_NOTES Telegram 103
Вот это по мне так самый интересный пост за всю эту серию.Есть одна ошибка которую совершают все при работе с фрагментами. Причем, под все я не сильно утрирую, за всю мою карьеру был только один проект, в котором про эту ошибку не забыли.

Начнем с простого, когда создаем фрагмент мы переопределяем метод onCreateView. В этом методе можно просто вернуть null. Это самый простой кейс как может быть Fragment без View. В этом случае немного изменяется ЖЦ фрагмента. В частности не вызывается метод onViewCreated, потому как View не создалась. Может возникнуть вопрос, а зачем это нужно? Для этого окунемся в историю.

Раньше в стародавние времена, не было такой штуки как ViewModel, которая умела переживать смерть Activity. Большие объекты сохраняли либо через статику, которая несет свои сложности, либо через retain фрагмент.

У фрагментов есть такая настройка setRetainInstance, которая позволяет указать нужно ли пересоздавать фрагмент при смерти Activity. Если выставляем retainInstance = true, то при пересоздании Activity фрагмент умирать не будет. Это позволяло использовать такие фрагменты, как сейчас, используются ViewModel. Однако есть важное ограничение. Нельзя делать такие фрагменты с View это может привести к утечкам памяти.

У View всегда есть ссылка на Activity (сейчас не рассматриваем кейс с виджетами), и соответственно у Activity всегда есть ссылка на View которую мы видим на экране. Когда умирает Activity, умирает и View которая к ней привязана. Фрагмент как мы помним это в некотором смысле сложная View. Если в retain фрагменте сохранить ссылку на View в поле этого фрагмента, то при перевороте у нас будет жить ссылка на старую Activity которая умерла: Fragment -> View -> Activity.

Из-за такой возможности легко сделать утечку памяти, а также из-за смешивания View и презентационной логики были сделаны ViewModel. Сейчас настройка retainInstance deprecated и очень не рекомендуется к использованию. retainInstance ушел в прошлое, правда иногда спрашивают на собесах.

Однако это еще не все интересные кейсы где может быть фрагмент без View.

Неочевидно поведение проявляется при транзакции с заменой фрагмента. Начнем с примера, у вас есть FirstFragment в Activity, затем мы делаем транзакцию с заменой фрагмента FirstFragment на SecondFragment. Что при этом происходит с FirstFragment?

Вот тут интересная часть, у него удаляется View, однако сам фрагмент какое-то время продолжает жить. Это сделано для оптимизации. Если нажмем на кнопку назад, то нам нужно будет создать заново фрагмент FirstFragment, а это накладные расходы т.к рефлексия и вот это все. Теперь вдумайтесь, обычный фрагмент, может в некоторых кейсах вести себя очень похоже на retain фрагмент. Да разумеется, он уничтожится при перевороте и тогда уже нет проблем. Однако не факт что этот переворот случится. Это именно тот момент когда можно подорваться и вот каким образом.

Самая распространённая ошибка это сохранение Adapter во фрагменте. Когда вы используете RecycleView вы обязаны создать Adapter чтобы с ним работать. Часто этот Adapter сохраняют в поле Fragment, потому как пересоздавать его каждый раз когда обновляются данные такая себе затея и это правильно. Однако в таком случае важно в onDestroyView зачищать ссылку на этот Adapter у RecyclerView:

recycler.adapter = null


Интересный факт о котором не пишет Гугл – Adapter держит ссылку на RecyclerView. И по факту мы можем оказаться в ситуации когда у нас фрагмент, который ведет себя как retain фрагмент, да еще и с ссылкой на View. Он конечно удалится со временем, однако не понятно когда, да и удалится ли вообще, до того момента, как умрет Activity.

Поэтому просто возьмите за правило – не сохраняйте ссылки на View в поля фрагментов, или очищайте их в onDestroyView, что делает ViewBindingPropertyDelegate. Помимо это затирайте ссылку на Adapter у RecyclerView.
🔥39👍18🤔32



tgoop.com/dev_easy_notes/103
Create:
Last Update:

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

Начнем с простого, когда создаем фрагмент мы переопределяем метод onCreateView. В этом методе можно просто вернуть null. Это самый простой кейс как может быть Fragment без View. В этом случае немного изменяется ЖЦ фрагмента. В частности не вызывается метод onViewCreated, потому как View не создалась. Может возникнуть вопрос, а зачем это нужно? Для этого окунемся в историю.

Раньше в стародавние времена, не было такой штуки как ViewModel, которая умела переживать смерть Activity. Большие объекты сохраняли либо через статику, которая несет свои сложности, либо через retain фрагмент.

У фрагментов есть такая настройка setRetainInstance, которая позволяет указать нужно ли пересоздавать фрагмент при смерти Activity. Если выставляем retainInstance = true, то при пересоздании Activity фрагмент умирать не будет. Это позволяло использовать такие фрагменты, как сейчас, используются ViewModel. Однако есть важное ограничение. Нельзя делать такие фрагменты с View это может привести к утечкам памяти.

У View всегда есть ссылка на Activity (сейчас не рассматриваем кейс с виджетами), и соответственно у Activity всегда есть ссылка на View которую мы видим на экране. Когда умирает Activity, умирает и View которая к ней привязана. Фрагмент как мы помним это в некотором смысле сложная View. Если в retain фрагменте сохранить ссылку на View в поле этого фрагмента, то при перевороте у нас будет жить ссылка на старую Activity которая умерла: Fragment -> View -> Activity.

Из-за такой возможности легко сделать утечку памяти, а также из-за смешивания View и презентационной логики были сделаны ViewModel. Сейчас настройка retainInstance deprecated и очень не рекомендуется к использованию. retainInstance ушел в прошлое, правда иногда спрашивают на собесах.

Однако это еще не все интересные кейсы где может быть фрагмент без View.

Неочевидно поведение проявляется при транзакции с заменой фрагмента. Начнем с примера, у вас есть FirstFragment в Activity, затем мы делаем транзакцию с заменой фрагмента FirstFragment на SecondFragment. Что при этом происходит с FirstFragment?

Вот тут интересная часть, у него удаляется View, однако сам фрагмент какое-то время продолжает жить. Это сделано для оптимизации. Если нажмем на кнопку назад, то нам нужно будет создать заново фрагмент FirstFragment, а это накладные расходы т.к рефлексия и вот это все. Теперь вдумайтесь, обычный фрагмент, может в некоторых кейсах вести себя очень похоже на retain фрагмент. Да разумеется, он уничтожится при перевороте и тогда уже нет проблем. Однако не факт что этот переворот случится. Это именно тот момент когда можно подорваться и вот каким образом.

Самая распространённая ошибка это сохранение Adapter во фрагменте. Когда вы используете RecycleView вы обязаны создать Adapter чтобы с ним работать. Часто этот Adapter сохраняют в поле Fragment, потому как пересоздавать его каждый раз когда обновляются данные такая себе затея и это правильно. Однако в таком случае важно в onDestroyView зачищать ссылку на этот Adapter у RecyclerView:

recycler.adapter = null


Интересный факт о котором не пишет Гугл – Adapter держит ссылку на RecyclerView. И по факту мы можем оказаться в ситуации когда у нас фрагмент, который ведет себя как retain фрагмент, да еще и с ссылкой на View. Он конечно удалится со временем, однако не понятно когда, да и удалится ли вообще, до того момента, как умрет Activity.

Поэтому просто возьмите за правило – не сохраняйте ссылки на View в поля фрагментов, или очищайте их в onDestroyView, что делает ViewBindingPropertyDelegate. Помимо это затирайте ссылку на Adapter у RecyclerView.

BY Dev Easy Notes


Share with your friend now:
tgoop.com/dev_easy_notes/103

View MORE
Open in Telegram


Telegram News

Date: |

In 2018, Telegram’s audience reached 200 million people, with 500,000 new users joining the messenger every day. It was launched for iOS on 14 August 2013 and Android on 20 October 2013. ZDNET RECOMMENDS How to Create a Private or Public Channel on Telegram? It’s easy to create a Telegram channel via desktop app or mobile app (for Android and iOS): Hui said the messages, which included urging the disruption of airport operations, were attempts to incite followers to make use of poisonous, corrosive or flammable substances to vandalize police vehicles, and also called on others to make weapons to harm police.
from us


Telegram Dev Easy Notes
FROM American