Разработка Под Android, Большие И Не Очень Грабли

Ниже я попытаюсь описать ряд неприятных особенностей, с которыми может столкнуться разработчик для платформы Android. Не все из них являются особенностью операционной системы Android, но так или иначе есть шанс с ними столкнуться.



Большие грабли

Как это произошло: Вы загружаете свое 10-мегабайтное приложение на Android Market, и получаете гневное письмо от пользователя — «Как можно делать такие ужасные программы, они даже не хотят устанавливаться на мой телефон, они меня обманывают. У меня на телефоне было свободно 15 мегабайт, я попробовала установить ваше приложение, в описании которого написано, что оно занимает 10 мегабайт - она мне сказала, что не хватает места, я удалила ненужные программы и у меня свободно 25 мегабайт - оно все равно пишет мало места, я удалил нужные мне программы и осталось 35 мегабайт свободного места - все равно не хочет устанавливаться.

Что за черт! Почему вы пишете неправильный размер для своей программы!» (мой вольный перевод с английского самого письма).

Причина: Чтобы установить приложение размером X мегабайт, вам потребуется от 2 до 4 раз свободного места.

Почему: Сначала файл приложения загрузится на устройство и займет там Х мегабайт места, затем его распакуют для тестирования - еще Х до 2Х мегабайт в среднем, затем он будет перемещен в приложения в файловой системе еще Х мегабайты.

Что делать: Если вы делаете приложение размером более 5 мегабайт, то будьте готовы написать функционал по скачиванию и размещению некоторых ресурсов на флешке, а также проверке возможного отсутствия флешки или удалению части ваших файлов, при этом приложение работает.

Грабли со встроенной флэш-памятью

Как это произошло: Вы создаете приложение с интенсивным использованием файлов.

Замеряешь время работы и получаешь вполне приемлемые цифры — накладные расходы на файловую операцию около 5 миллисекунд. Приложение работает быстро, вы довольны.

Установив ряд приложений, вы заметите, что время работы вашей программы увеличилось в 5 раз.

Причина: Особенности реализации файловой системы – чем меньше свободного места на флешке, тем дольше выполняются файловые операции.

Время доступа увеличивается с 5 мс до 300 мс; теоретически время доступа может увеличиться до 200 раз.

Почему: Файловая система пытается поддерживать работоспособность вашего флэш-накопителя, поэтому она отслеживает интенсивные файловые операции и пытается переместить часто необходимые файлы с места на место.

Чем больше файлов и меньше свободного места, тем больше времени это занимает. Что делать: Вместо множества маленьких файлов один большой файл с индексами.

И будем надеяться, что никто не будет пользоваться вашим приложением месяцами и не убьет свою флешку.



Грабли ограничены

Как это произошло: Вы получаете прототип нового Android-планшета с размером экрана 1280 на 800 и целым гигабайтом памяти на борту.

В радостном предвкушении вы начинаете портировать свой квест - загружаете первый полноэкранный задник, второй, шестой - и получаете OOME (OutOfMemoryError).

Причина: 16 МБ памяти на каждый процесс (24 МБ на N1/Desire), включая «собственную кучу», где хранятся растровые изображения (и текстуры OpenGL).

Почему: В лучших традициях диктаторской демократии лучше предоставить всем приложениям доступ к небольшому объему памяти, чем позволить одному приложению использовать всю память, что может вызвать проблемы для других приложений.

Ну и много других нюансов.

Что делать: 640кб 24мб памяти хватит всем

Чувствительные грабли

Как это произошло: Вы создали свое приложение, добавили классную музыку и добавили элементы управления акселерометром.

Пользователи жалуются, что управление ужасное.

Причина: При воспроизведении музыкального трека на максимальной громкости, особенно там, где много басов, при неподвижном телефоне значения вращения, снимаемые с датчиков, меняются от -10 до +10 градусов.

Почему: Динамик расположен слишком близко к датчикам Что делать: Не допускайте установки музыки на максимальную громкость, не используйте хэви-метал треки, учитывайте тремор сенсора

Грабли с поддержкой MultiTouch

Как это произошло: Хотите сделать управление, например, как в игре iDracula?


Разработка под Android, большие и не очень грабли

И ты не можешь.

Причина: Вы получаете координаты касания парами — две координаты X, две координаты Y. Вы не можете узнать, какому касанию принадлежит та или иная координата.

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

Я понимаю, что описание довольно расплывчатое - поэтому можете посмотреть это видео - Или загрузите на телефон приложение MultiTouch Visualizer. Почему: Особенности реализации сенсора на некоторых моделях телефонов – Nexus One, Desire. Что делать: Откажитесь от такого управления, либо распределите его по координате Y.

Волшебные грабли

Как это произошло: Вы пишете следующий код

while(true) { Task task = queue.getTaskBlocking(); task.execute(); }

Где Task — довольно «толстый объект», выделяющий много памяти.

И вы обнаружите, что используется больше памяти, чем планировалось.

Посмотрев получившийся байт-код, вы обнаруживаете, что он компилируется не в тот код, который вы хотели, а именно в тот код, который вам нужен.



Task task; while(true) { task = queue.getTaskBlocking(); task.execute(); }

В результате у вас есть два экземпляра Task в памяти.

Не беда, думаете вы, мы сейчас явно укажем, что один экземпляр можно удалить из памяти.



while(true) { Task task = queue.getTaskBlocking(); task.execute(); task = null; }

Но взглянув на полученный байт-код, вы увидите, что оптимизатор решил, что, поскольку переменная выходит за пределы области видимости, он выбросил ваше явное обнуление объекта, и у вас все еще есть два экземпляра в памяти.

И тогда рождается волшебство.



class Magic { static private int n = 0; static public void doMagic(Object obj) { if (obj != null) n++; } static public int getMagic() { return n; } } while(true) { Task task = queue.getTaskBlocking(); task.execute(); task = null; Magic.doMagic(task); }

Причина: Бага :) Почему: // TODO: Найдите ответственного за это разработчика, помучите и выясните почему.

Что делать: Магия Теги: #Android #программирование #ошибка #магия #разработка Android

Вместе с данным постом часто просматривают: