Разбор частых проблем кодинга Android-разработчика

проблемы кодинга Android разработчика

Двадцать лет назад использовать Android было невозможно. Десять лет назад было еще рано. Сегодня — уже поздно. Конечно, я утрирую, но, когда операционная система молода, многие ее недостатки можно списать на «детские болезни». Их можно понять, простить и не замечать, ожидая скорейших багфиксов от компании-производителя, но… Android уже дорос, пожалуй, до бальзаковского возраста, а мы все так же решаем проблемы, которые давным-давно должны быть исправлены. Сегодня мы рассмотрим те затруднения при разработке под Android, с которыми ты точно когда-нибудь столкнешься. И которые, кстати, дико бесят.

Рекомендуем: Инструменты Android-разработчика

Жизненный цикл Activity может в любой момент перечеркнуть все твои планы

Если вы программируете под Android, то наверняка встречали схему жизненного цикла для самой простой активити. А знал ли вы жизненный цикл окошка с кнопочками, которое создавал компилятор старого и доброго Delphi? Я думаю — нет, не знали, и знать вам это было не нужно. Интересно, как бы на вас посмотрели олдскульные дельфисты-паскалисты, если бы вы им сказали: «когда пользователь перевернет свой экран, нам надо пересоздать все формы и восстановить состояние всех компонентов». Скорее всего, они бы пальцем у виска покрутили. И не только потому, что переворачивать старые мониторы и системные блоки было не принято.

А меж тем Android именно так и устроен: повернул экран — начинай все сначала. Конечно, в настройках вы можете отключить поворот экрана, но это не всегда удобно, да и рядовые пользователи не знают и десяти процентов возможностей своего смартфона. Поэтому сейчас имеем мы то, что имеем, и единственное, что вы можете сделать при разработке, — это отключить в манифесте пересоздание Activity, добавив свойства

Конечно, «знающие люди» так делать не рекомендуют, но такой костыль используют даже серьезные социальные приложения. Если не верите — посмотрите сами манифесты из их APK.

Дело осложняют и сами производители устройств — каждый из них адаптирует ОС к своим устройствам, меняя в том числе ее поведение. Например, традиционно рекомендуется сохранять данные при событии onStop. Пользователь свернул приложение, и вызвался этот метод. Но есть одна проблема: на некоторых устройствах вызов этого метода не гарантирован. В таком случае нужно сохранять все, что можете, в методе onPause. Правда, он вызывается не только при выходе из активити, но и при показе диалогового окна, поэтому нужно предвидеть этот момент и предусматривать проверки на показ диалога.

Сбор ошибок, которого не было

Я с тоской вспоминаю старые времена виндовой разработки. Кому нужны системы для сбора ошибок? Да никому! Большинство ошибок лежало «на поверхности», программа или работает, или нет. Если она периодически вылетает — значит, «проклятая винда опять глючит». А если она вылетает по вине программиста, то и не страшно, ведь онлайн-сторы программного обеспечения еще не придумали и никто не засыплет вашу софтину минусами и гневными комментариями. Максимум — под пивко поплачет в жилетку своему дилеру пиратского ПО на Митинском радиорынке.

Сегодня вы лично, оперативно и максимально прозрачно отвечаете за каждый свой begin и end в Kotlin-коде. Поэтому собирать ошибки нужно сразу при старте приложения.

Систем сбора сейчас расплодилось превеликое множество, но лично я пользуюсь Crashlytics. В ее пользу говорит и то, что ее недавно купила сама Google. Включать сбор ошибок можно для каждой активити отдельно, но проще сразу включить его в классе Application:

Выполнение кода в этом месте может затянуть показ первого экрана приложения, но туда можно через тему поставить свой Splash и убить сразу двух зайцев — подгрузить инструменты и развлечь пользователя.

Как видно из приведенного выше кода, один инструмент Google — Crashlytics — следит за работой другого — Firebase. Несмотря на то что оба они могут выполнять одинаковые задачи — собирать события, Crashlytics действует так:

А Firebase — вот так:

Теперь я стреляю у девушек телефон… чтобы отловить на нем баги

Про изменение прошивки производителем вы уже слышали. Но как быть, если неприятность уже случилась и ваше приложение, к примеру, стабильно падает у производителя X на устройстве Y с прошивкой Z?

Все бы ничего — подумаешь, одно падение у одного устройства. Но таких устройств было продано несколько миллионов штук, так что гневных отзывов и однозвездных комментариев вас ждет несколько десятков. Как быть? Использовать фермы для тестирования.

Из халявных инструментов я бы предпочел Firebase, который на бесплатном тарифе дает прогнать тесты по десяти реальным устройствам. Кроме того, не забывайте погуглить собственные веселые фермы от разработчиков смартфонов. И заводи контакты с людьми, которые работают в магазинах электроники или сервисных центрах (особенно неплохо это получается в маленьких городах). Тогда вы сможете делать, как я, — брать устройства для тестов у них. Главное, не забудьте вернуть гаджет в первоначальное состояние и скройте меню для разработчиков, если оно было заблокировано ранее.

Хотите меньше багов в приложении? Выкидывай фрагменты и асинктаски (лоадеры тоже не забудьте)

Говорят, что секрет 99,9% удачных пусков приложения — в отказе от фрагментов в любом виде. Дело в том, что у разных производителей они порой выкидывают такие замысловатые ошибки, что понять их можно только с помощью хрустального шара. Если шаром вы владеть не обучены, лучше вовсе отказаться от фрагментов. Тот же ViewPager можно сделать и без них.

Асинктаски можно использовать для разовых фоновых запросов, но, если нужно много работы делать в фоне, используйте другие инструменты (Rx, сервисы). Ну а лоадеры имеют старый баг, связанный с тем, что колбэки о завершении могут вообще не вызываться. Говорят, что в новых версиях это исправили, но проверять я бы не стал (они так каждые полгода говорят).

Рекомендую: Полезные советы разработчику на языке Kotlin

Фрагментация ухудшает внешний вид

Огромный парк разноформатных устройств — одновременно баг и фича мира Андроида. Из-за большой фрагментации приходится вымерять разметку под каждую плотность экрана. Редактор макетов экранов при этом крайне неудобный. Из-за этого особо отчаянные (Telegram) вообще его не используют, а генерируют экраны динамически, из кода.

А как там с редизайном стандартных меню и вкладок? Легко! Два дня вдумчивого гугления, ящик пива, блок сигарет, пробы, ошибки, несколько костылей — и пожалуйста, приложение выглядит почти как нарисовал дизайнер.  Уверен, что «отличные» компоненты DrawerLayout и ViewPager отлично научат вас пользоваться поиском при любом нестандартном поведении или когда просто захотите сменить шрифты в меню.

Библиотекам поддержки самим нужна «помощь и поддержка»

Серьезно, каждый новый релиз — новые костыли! Почти все компоненты из библиотеки поддержки несут неизлечимые баги, которые не исправляются годами. У меня было несколько ошибок, которые умерли вместе с устройствами, но так и не были исправлены. К примеру, отличный класс для уведомлений NotificationCompat меняется каждую версию Android, и вы меняете свой код вслед за ней.

Библиотеки поддержки очень большие и сами тянут в проект библиотеки для поддержки. Программисты даже шутят: «Каждый класс в этих библиотеках будет иметь суффикс CompatCompat». Кстати, чтобы увидеть, что тянет та или иная библиотека за собой, можно воспользоваться инструментом gradle — dependencies.

проблемы кодинга Android-разработчика
Дерево зависимостей

Для удаления хотя бы части ненужного кода можно прописать правило для gradle:

После отработки правил исключения не забудьте еще раз все протестировать.

«Мы хотели помочь вам c разметкой и написали Constraint Layout, но он падает и тормозит»

Новинка, которая должна была упростить нам жизнь, — Constraint Layout, — сложна в использовании, и приложение из-за нее становится тяжелее и медленнее. Чтобы работать с этим инструментом эффективнее, советую прочесть статью. А в преддверии версии Constraint Layout 2.0 можно изучить это выступление. По слухам, его представят на Google IO 2018.

Просто записать файл на флешку не получится: спроси разрешения, а лучше городи контент-провайдер

Сама идея ограничивать доступ программ к файловой системе — благая и по сравнению с «виндовой вольницей», где каждый делает, что хочет, конечно, секьюрная. Но какой же это геморрой, коллеги!

Перекинуть данные через простой файл не разрешает сама ОС. Хотите обмена? Пишите контент-провайдер. Точно нужно записать что-нибудь на диск? Реально нужно? Извольте спросить у пользователя кучу разрешений и заранее продумать, что делать, если он их вам не даст.

Рекомендуем: Что должен знать начинающий Андроид-разработчик

Все стандартные медиакомпоненты просто ужасны

Максимум, на что способны классы VideoView, MediaPlayer и SurfaceView, — заставить вас чесать репу и просиживать долгие часы за компьютером. Если вам нужен результат, то ищите сторонние библиотеки. Пусть чужой опыт сэкономит вам время и нервы. Вот хороший плеер.

Для работы с камерой изучите «Побеждаем Android Camera2 API с помощью RxJava2».

Как лучше проигрывать музыку? Подсмотрите у Timber и Phonograph.

Любой желающий может декомпилировать ваше приложение и изменить его, как захочет, — оно просто создано для этого

Исторически сложилось так (и это уже точно не исправить), что код для Android работает в виртуальной машине. Кому пришло в голову поднимать на низкопроизводительных ARM-процессорах виртуалки? Вряд ли теперь мы это узнаем. Apple сделала все, как надо, и завоевала приз наших зрительских симпатий, а вот «корпорация добра» решила извратиться, и теперь нас напрягает (спасибо современным процессорам) даже не производительность, а тот факт, что исходный код приложения можно восстановить почти что до запятой.

Пишите свой код качественнее, и его будут читать не только китайские хакеры, но и программисты из развитых стран — считайте это успехом. 😉 А стоит вам пренебречь обфускацией, и любой школьник сможет модифицировать вашу программу и сделать на ее основе свой шедевр.

Понравилась статья? Поделиться с друзьями:
Добавить комментарий