[Из песочницы] Мелочи разработки на Android для начинающих
В связи со стремительным развитием мобильных технологий, IT-компаниям все больше требуются разработчики мобильных приложений для своих продуктов. Наша компания не стала исключением. В моем распоряжении оказалось два падавана, которых надо было обучить премудростям разработки на Android (к слову сказать, парни были умные и способные, но практически без опыта). Было решено написать им небольшую памятку касательно основных аспектов разработки. Выкладываю ее на суд хабрапользователей.Описания своих рассуждений выложу под спойлеры.UIВо-первых, не пользуйтесь визуальным конструктором. Никогда. Исключение — совсем уж начинающий разработчик, который не знает основ xml разметки Android, и то, при условии, что он потом вручную пройдется по разметке и вычистит весь мусор.Спойлер
Проблема заключается в том, что визуальный конструктор — это не Android, а отображаемый там View — это не все ваше приложение, поэтому при попытке выставить его правильно конструктор может использовать отступы вместо центрирования, LinearLayout вместо FrameLayout или вообще, просто излишнюю вложенность. Как-то раз наткнулся на такой кусок верстки (сокращу атрибуты для наглядности), никогда так не делайте:
Во-вторых, не используйте RelativeLayout где попало. Если вы хотите поставить View по порядку, то LinearLayout к вашим услугам. Если все ваши View строго позиционированы, то всегда можно прибегнуть к FrameLayout.
Спойлер Встречаю практически повсеместно, но почему-то не все понимают, что разные типы View грузятся разное время. RelativeLayout самый тяжелый и долгий, FrameLayout один из самых легких (из элементов, которые могут содержать в себе дочерние View). И если для root-элемента Activity это никак не скажется, то для списков это будет заметное подтормаживание.P.S. Это не призыв отказаться от RelativeLayout, в некоторых случаях без него действительно никак. Но только в некоторых. Не во всех!
В-третьих. Margin или padding? Если вы хотите сделать удобный кликабельный элемент, то padding и только он! Если вам необходим отступ, который будет у неактивного элемента, то тогда допускается использование margin.
Спойлер Истина проста. Чем элемент больше, тем его удобнее нажимать. Margin — отъедает место у самого элемента, padding — у окружения. Не даром отступы есть даже у изображений, причем строго указанные и задокументированные для всех разрешений. Пожалуйста придерживайтесь этих правил, они сильно облегчат жизнь вам и вашим пользователям. В-четвертых. Не забывайте, xml ничуть не менее код, чем та часть которую вы пишите на Java. Поэтому следите за тем что бы дублирование xml разметки было сведено к минимуму, по возможности создавайте свои элементы управления, если они будут использованы в нескольких местах (да и если не в нескольких, то тоже лучше создать отдельно).
Спойлер Этот совет скорее для пользы разработчику, а не пользователю, так как рано или поздно все равно придется менять поведение или представление у различных контролов вашего приложения. Вам же будет легче если все они будут в одном месте и аккуратно отсортированы.
Асинхронность Во-первых, помните, количество асинхронных потоков ограничено. Ограничено 5-ю штуками. При этом реально их еще меньше: 1 поток отъедает UI, если ваше приложение работает с сетью, то еще один поток на сеть, зарезервируем еще один поток для работы с БД в асинхронном режиме и в итоге на реализацию различных фич остается 2 потока. Если делать их правильно, то этого вполне хватает (за очень редким исключением).Спойлер Пруф: http://dolbodub.blogspot.ru/2013/03/asynctask.html– классная статья про асинхронность. Несмотря на то, что потоков в андройде может быть достаточно много, тем не менее следует понимать что с 5-го по 10-й поток будут стоять в очереди, более того, если поток встал в очередь он не будет запущен параллельно при последующем наличии вакантных мест. Это скорее гарантия того, что ваше приложение не упадет, при использовании большого числа потоков, чем гарантия его стабильной и комфортной работы. Во-вторых, не работайте из второстепенных потоков с UI. Вообще.
Спойлер Про то, что нельзя обращаться к отрисованному UI из неглавного потока — думаю знают все, так как это грозит выпадением исключения. Но вот некоторые разработчики не знают, что во второстепенном потоке нельзя даже создать UI элемент. Дело в том, что на каких-то устройствах работать с UI разрешено только в главном потоке, на каких-то устройствах главный поток требуется только для отрисовки UI, поэтому если у разработчика не будет девайса для первого случая, то есть вероятность допуска такой ошибки.
База данных Тут будет только один пункт, касательно самой распространенной БД на Android — SQLite. Она медленная. Очень. Не пренебрегайте ее оптимизацией и асинхронной работой с ней.Спойлер Этот факт не заметен на проектах с маленьким или статичным набором данных, но если приложение требует постоянных синхронизаций больших объемов данных (например, offline клиент для большого склада), то одновременное обновление и работа приложения могут быть затруднены или даже невозможны. Связано это с одной простой особенностью SQLite: она либо читает из БД, либо пишет, никак не враз (не учитываем такую вещь как грязное чтение, потому что новичку лучше к ней не прибегать кроме крайне необходимых случаев).
Тестирование Ни для кого не секрет, что хорошее приложение — протестированное приложение. Поэтому не следует пренебрегать такими вещами, как комплексное и модульное тестирование, рецензирование кода другим разработчиком. Стесняться тут нечего, хороший программист не тот, кто не допускает ошибок, а тот, кто их находит и учитывает в будущем.Говоря о советах могу сказать, что лучше использовать интерфейсы для всего, что работает не только с внутренним устройством вашего приложения (например, адаптеры для работы с сетью, для работы с другим приложением, бд). Потом при тестировании себе «спасибо» скажете.
Спойлер Вся соль в том, что при модульном тестировании намного проще писать тест, если ты гарантировано знаешь что тебе придет на определенный запрос. В случае работы с внешними источниками (даже если они 100% доступны) всегда можно испортить их набор данных предыдущим тестом. В случае работы с интерфейсом можно просто создавать в тесте класс-заглушку, которая будет возвращать то, что вам нужно.
Локализация и ресурсы Никогда не используйте захардкоденные строки. Используйте ресурсы (R.string.your_string). Даже если у вас нет и никогда не будет поддержки нескольких языков.Спойлер Во-первых, когда ваши строки выгружены в отдельный файл — с ними намного проще работать — и вам, и человеку, который будет проверять их на грамотность написания (да-да, за программистами есть такой грешок, что после написания тысяч строк кода родной язык начинает забываться, да и о банальных опечатках забывать нельзя).Во-вторых, даже если вы считаете, что поддержки нескольких языков приложения никогда не будет — вы ошибаетесь. Если проект хоть что-то стоит, то его имеет смысл перевести хотя-бы на английский. Захардкоденные строки в этом случае потом вытащить крайне сложно.
Обратите внимание, насколько большое существует количество различных группировок ресурсов: по языку, по разрешению экрана, его ориентации и размеру, по стране и пр. Довольно большая часть этого, возможно, вам никогда не потребуется, но ознакомиться с ними надо. В будущем при проблемах отрисовки/расположения элементов на различных устройствах это сэкономит вам уйму времени.