Грабли большого размера
Как это происходит: Вы выкладываете свое приложение размером в 10 мегабайт в Android Market, и вам приходит гневное письмо от пользователя — «Как можно делать такие ужасные программы, она даже не хочет устанавливаться на мой телефон, она меня обманывает. У меня было 15 мегабайт свободно на телефоне, я попытался установить ваше приложение в описании которого написано что оно занимает 10 мегабайт — она мне сказала что места не достаточно, я удалил ненужные программы и у меня 25 мегабайт свободно — все равно говорит не достаточно места, я удалил программы которые нужны мне и стало 35 мегабайт свободного места — она все равно не хочет устанавливаться. WTF! Зачем вы пишите неверный размер своей программы!» (мой вольный перевод с английского реального письма).
Причина: Для установки приложения размером X мегабайт, нужно от 2X до 4X свободного места.
Почему: Сначала файл приложения скачается на устройство и займет там X мегабайт места, потом он будет распакован для проверки — еще от X до 2X мегабайт в среднем, потом он будет перемещен в приложения в файловой системе еще X мегабайт.
Что делать: Если вы делаете приложение больше 5 мегабайт размером, то будьте готовы писать функциональность для скачивания и размещения на флэшке части ресурсов, а так же проверки на возможное отсутствие флэшки или удаление част ваших файлов, причем в процессе работы приложения.
Грабли со встроенной флэш памятью
Как это происходит: Вы делаете приложение интенсивно работающие с файлами. Замеряете время работы и получаете вполне приемлемые цифры — оверхэд файловой операции порядка 5 миллисекунд. Приложение работает быстро, вы довольны. После установки ряда приложений, вы замечаете что время работы вашей программы выросло в 5 раз.
Причина: Особенности реализации файловой системы — чем меньше свободного места на флэшке, тем больше времени занимают операции с файлами. Время доступа вырастает с 5 мс до 300мс, в теории время доступа может вырасти до 200 раз.
Почему: Файловая система пытается сохранить жизнь вашей флэшки, поэтому отслеживает интенсивные операции с файлами и часто востребованные файлы пытается перемещать с места на место. Чем больше файлов, и чем меньше свободного места, тем больше ей на это нужно времени.
Что делать: Вместо множества маленьких файлов, один большой файл с индексами. И будем надеяться что никто не будет использовать ваше приложение месяцами и не убьет свою флэшку.
Грабли ограниченные
Как это происходит: Вам приходит прототип нового планшета на Android c размером экрана 1280 на 800 с целым гигабайтом памяти на борту. Вы в радостном предвкушение начинаете портировать ваш квест — загружаете первый полноэкранный задник, второй, шестой — и получаете OOME (OutOfMemoryError).
Причина: 16Мб памяти на процесс (24Мб на N1/Desire), это включает себя «нативную кучу», где хранятся Bitmap (и OpenGL текстуры)
Почему: В лучших традициях
Что делать:
Чувствительные грабли
Как это происходит: Вы создали ваше приложение, добавили туда классную музыку, добавили туда управление с использование акселерометра. Пользователи жалуются что управление ужасное.
Причина: При проигрывания музыкального трека на максимальной громкости, особенно где много басов, при неподвижном телефоне значение поворота снятые со сенсоров меняются от -10 до +10 градусов.
Почему: Динамик слишком близко расположен к сенсорам
Что делать: Не давать выставлять музыку на максимальную громкость, не использовать треки в стиле heavy metal, учитывать тремор сенсоров
Грабли с поддержкой MultiTouch
Как это происходит: Вы хотите сделать управление, например как в игре iDracula
И не можете.
Причина: Вы получаете координаты касания парами — две 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;
}
Но посмотрев на результирующий байт код вы видите, что оптимизатор решил что так как переменная out of scope, выкинул ваше явное зануление объекта, и у вас все равно два экземпляра в памяти. И тогда рождается магия.
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: Найти разработчика отвечающего за это, пытать и узнать почему.
Что делать: Магия