Классная статья, со всем согласен.
И меня очень пугает тенденция: специалисты заваливаются на фундаментальных вещах. Примерно половина моих кандидатов валилась на базовых принципах ООП (собес Java). Примерно 80% кандидатов никогда не слышали про индекс баз данных. Ну и в таком духе.
Чем дальше — тем больше Framework- и Stakeoverflow разработчиков. И что примечательно: это кандидаты 22-27 лет. У старших ситуация с «фундаментом» лучше, как правило.
Я не писал про гарантии и панацею. И я ни в коем случае не отрицал полезность тулзов для мониторинга памяти и статьи в целом.
Но проблемы с лишними ссылками на объекты (коим посвящено >50% статьи) возникают именно по причинам не следования принципам ООП.
Конечно же есть много других причин утечек памяти. Но именно описанные в статье проблемы решаются продуманной архитектурой и знанием инструментов SDK.
Но я бы половину текста заменил 3-мя пунктами:
1. Придерживайтесь принципов ООП.
2. Используйте инструменты (классы, менеджеры, механизмы), предоставленные Android SDK.
3. Прочтите какую-нибудь книгу про «чистый код».
Например:
— Абстракция и инкапсуляция в кУпе с различными менеджерами SDK не дадут образоваться большей части описанных утечек.
— Использование локальных переменных вместо полей класса значительно облегчит работу сборщика мусора.
— …
И таких моментов много, которые следуют из основ. Читайте книги, они очень полезны.
Соглашусь, что фрагменты не всегда работают одинаково на разных версиях Android.
И да, утечки в памяти тоже наблюдались.
Тем не менее, фрагменты — очень важный и неотъемлемый класс Android SDK. Совсем не тяжело заставить работать фрагменты как нужно, и подстроиться под особенности LifeCycle.
Custom View хоть и является альтернативой, но по-моему есть велосипед и игнорирование опыта многих хороших разработчиков.
Решение — действительно костыль. Подбор какого-либо числа исходя из девайса — признак неверного решения. Скажем, на LG Optimus Link — 300 мс мало. Нужно хотя бы 500.
Оптимальным считаю следующий вариант:
по клику на пункт меню — записать в переменную (скажем pendingFragment) фрагмент, который нужно показать. И выполнить транзакцию по событию OnDrawerClosed() в DrawerListener.
Решение не мое, но оно мне нравится:
1. Идеально сработает на любом девайсе
2. Не увеличит количество костылей в Вашем коде
Picasso интегрится предельно просто и быстро, потому попробовать нужно. Хотя бы просто для опыта. Возможно, работа библиотек как-то разнится от количества уже занятой приложением памяти. Или с GC они «дружат» по-разному. Я тестил на пустышке, а в вашем случае Picasso может справиться лучше остальных.
Честно говоря, не увидел этой библиотеки в комментариях, потому проигнорировал.
Я за неделю добавлю тест и этой библиотеки и выложу результат на GitHub. О готовности отпишусь в комментариях к этой статье.
Пока что UIL. На тест Picasso подтолкнула постоянная проблема с бесконечной сборкой мусора и OutOfMemory на старых устройствах. Но планирую пробу заинтегрить Picasso.
1. С UIL-ом такая комбинация точно работает. В конфигурации можно установить кастомный ImageDownloader, который экстендит библиотечный. Там и можно настроить хедеры и выполнить авторизацию перед запросом. Я использую в одном проекте. А вот с Picasso — не уверен, нужно смотреть.
2. Нужно тестировать. Но, поскольку, библиотека использует пул потоков для загрузки — то скорее всего Threads никуда не деваются при сворачивании Activity. А если нужно остановить\восстановить запросы по onStart()/onPause() — обе библиотеки поддерживают такую возможность.
И меня очень пугает тенденция: специалисты заваливаются на фундаментальных вещах. Примерно половина моих кандидатов валилась на базовых принципах ООП (собес Java). Примерно 80% кандидатов никогда не слышали про индекс баз данных. Ну и в таком духе.
Чем дальше — тем больше Framework- и Stakeoverflow разработчиков. И что примечательно: это кандидаты 22-27 лет. У старших ситуация с «фундаментом» лучше, как правило.
Скажите, а сколько Android-разработчиков в Вашей команде?
Цель — получить список ссылок на тот или иной объект.
Но проблемы с лишними ссылками на объекты (коим посвящено >50% статьи) возникают именно по причинам не следования принципам ООП.
Конечно же есть много других причин утечек памяти. Но именно описанные в статье проблемы решаются продуманной архитектурой и знанием инструментов SDK.
Но я бы половину текста заменил 3-мя пунктами:
1. Придерживайтесь принципов ООП.
2. Используйте инструменты (классы, менеджеры, механизмы), предоставленные Android SDK.
3. Прочтите какую-нибудь книгу про «чистый код».
Например:
— Абстракция и инкапсуляция в кУпе с различными менеджерами SDK не дадут образоваться большей части описанных утечек.
— Использование локальных переменных вместо полей класса значительно облегчит работу сборщика мусора.
— …
И таких моментов много, которые следуют из основ. Читайте книги, они очень полезны.
И да, утечки в памяти тоже наблюдались.
Тем не менее, фрагменты — очень важный и неотъемлемый класс Android SDK. Совсем не тяжело заставить работать фрагменты как нужно, и подстроиться под особенности LifeCycle.
Custom View хоть и является альтернативой, но по-моему есть велосипед и игнорирование опыта многих хороших разработчиков.
Оптимальным считаю следующий вариант:
по клику на пункт меню — записать в переменную (скажем pendingFragment) фрагмент, который нужно показать. И выполнить транзакцию по событию OnDrawerClosed() в DrawerListener.
Решение не мое, но оно мне нравится:
1. Идеально сработает на любом девайсе
2. Не увеличит количество костылей в Вашем коде
Я за неделю добавлю тест и этой библиотеки и выложу результат на GitHub. О готовности отпишусь в комментариях к этой статье.
compile 'com.squareup.picasso:picasso:2.1.1@jar'
compile 'com.nostra13.universalimageloader:universal-image-loader:1.9.0@jar'
memClass / 8 — почему именно этот коэффициент?
Всегда волновал вопрос, как правильнее высчитать размер кеша.
2. Нужно тестировать. Но, поскольку, библиотека использует пул потоков для загрузки — то скорее всего Threads никуда не деваются при сворачивании Activity. А если нужно остановить\восстановить запросы по onStart()/onPause() — обе библиотеки поддерживают такую возможность.