Программирование мобильных устройств на платформе .NET Compact Framework - Иво Салмре
Шрифт:
Интервал:
Закладка:
■ Типы, которые преобразуются (или, как еще говорят, "'упаковываются") в объекты. Наиболее распространенным типом значений, используемым в графических кодах, является структура System.Drawing.Rectangle. Обычно работа с типами, соответствующими значениям, отличается высокой эффективностью, поскольку их можно размещать в стеке (а не в глобальном пуле свободной памяти, или куче, как объекты). В то же время, значения также могут рассматриваться как объекты и размещаться в массивах или коллекциях или передаваться всюду, где допускается использование объектного типа. Тщательно следите за тем, чтобы не происходило неявное постоянное распределение и освобождение памяти, обусловленное "упаковкой" значений в объекты и их обратной "распаковкой".
Заботясь о том, чтобы в графическом коде приложения не выполнялось непрерывное создание и уничтожение часто используемых объектов, вы не должны забывать о необходимости следить за использованием глобальной памяти своего мобильного приложения. Если в графических функциональных возможностях нуждаются лишь отдельные части приложения, то следует подумать об освобождении занимаемых ими ресурсов, как только приложение входит в состояние, в котором в течение некоторого времени графические ресурсы ему не будут нужны. Хорошей практикой проектирования считается использование конечного автомата и определение тех графических ресурсов, от которых при выходе приложения из определенных состояний можно освободиться.
Резюме
От того, что вы напишете код, обеспечивающий отличную реакцию пользовательского интерфейса, алгоритмы вашего приложения работать быстрее не станут. Это никоим образом не ускорит победный марш разработки приложения "до полного завершения". Более того, код приложения может даже усложниться. Единственная причина, по которой следует заботиться о высокой реактивности интерфейса и стремиться к высокой производительности его кода, заключается в том, чтобы создать для пользователя более комфортные условия, но разве ради этого не стоит потрудиться? Если вы хотите, чтобы пользователь поставил самую высокую оценку вашему приложению, вы не должны жалеть времени на доводку и отшлифовку таких вещей, как способность интерфейса к отклику. Как и в случае других аспектов производительности, выполнение этой работы нельзя откладывать до завершающих этапов процесса разработки. В конце разработки вы еще смогли бы добавить что-то наподобие курсоров ожидания в тех точках, где приложение может тормозиться, но это все равно, что красиво покрасить фасад плохо построенного дома — это лучше, чем вообще ничего, но, в сущности, не так уж и много. Никогда не забывайте о необходимости обеспечения высокой интерактивности пользовательского интерфейса и всегда в явном виде включайте это требование в качестве критерия прохождения каждой контрольной точки разработки. Лучше всего решать подобные проблемы сразу же после их выявления, пока они не успели накрепко зацементироваться в структуру приложения.
В основе высокой производительности пользовательского интерфейса лежит активное управление условиями взаимодействия с ним конечного пользователя. Ваше мобильное приложение должно обеспечивать такие условия, при которых пользователь в процессе навигации в пределах приложения чувствует его ответную реакцию и не испытывает раздражения. Пользовательский интерфейс инициирует сложнейшую систему взаимодействий между кодом приложения и библиотеками времени выполнения, поверх которых приложение построено. Этот процесс сопровождается созданием элементов управления, используемых для заполнения форм, генерацией событий, а также многочисленными видами взаимодействия различного уровня между кодом и средой выполнения. Высокая производительность обеспечивается использованием оптимизированных в этом отношении средств среды выполнения, структурированием кода пользовательского интерфейса таким образом, чтобы пользователь не чувствовал себя изолированным от вычислительного процесса при выполнении задач, требующих длительного времени, а также целенаправленной количественной оценкой эффективности кода пользовательского интерфейса и включения в него средств контроля хода выполнения, которые позволят вам разобраться в том, что именно происходит за кулисами пользовательского интерфейса.
Изучайте свойства и методы элементов управления, которые вы используете. Для элементов управления часто предусматриваются специальные возможности оптимизации производительности. Внимательно анализируйте события, на которые реагирует ваше приложение. В частности, вы должны постараться хорошо представлять себе и экспериментально проверять, когда именно запускаются события, на которые приложению приходится реагировать. В процессе просмотра кода события могут казаться вам простыми и понятными, но они представляют ту область, в которой вы, как разработчик, вынуждены передавать управление выполнением приложения операционной системе. Именно операционная система и каркас пользовательского интерфейса определяют, когда именно будет выполняться код вашего обработчика события; это может случаться гораздо чаще, чем вы думаете, или происходить неожиданным для вас образом при обработке сообщений операционной системой. Между событиями, свойствами и методами элементов управления могут существовать такие тонкие виды взаимодействия, о которых вы даже не догадываетесь. Непредусмотренная и не являющаяся необходимой обработка событий пользовательского интерфейса порождает проблемы производительности и усложняет работу с приложением. Будьте особенно внимательны в тех случаях, когда существует возможность повторного входа в обработчик событий.
При работе с растровыми изображениями существенное значение имеют их размеры. Современные цифровые изображения с высоким разрешением занимают очень много места как на диске, так и в памяти. Цифровые фотографии, а также битовые образы, генерируемые на настольных компьютерах, представляют собой изображения, разрешение которых намного превышает возможности мобильных устройств. Никогда не забывайте о размерах экранов устройств, с которыми вы работаете, и размерах переносимых на них битовых образов; они должны соответствовать друг к другу. Для изображений, размеры которых довольно велики, неплохо использовать сжатые форматы хранения данных. В случае изображений, допускающих применение сжатие с потерями, рекомендуется использовать формат JPEG, тогда как в случае изображений, требующих полной достоверности, более подходящим является формат PNG. Помните, что, независимо от эффективности используемого алгоритма сжатия, занимаемый загруженным изображением объем памяти определяется размерами самого изображения.
Обработку графики следует продумывать независимо от кодирования высокоуровневого пользовательского интерфейса и оптимизировать отдельно. Оптимизация графического кода, предназначенного для рисования изображений, требует применения иных методик, нежели настройка кода высокоуровневого пользовательского интерфейса, и требует особого искусства. Поскольку графические изображения, генерируемые вашим мобильным приложением, обычно должны сосуществовать с элементами высокоуровневого пользовательского интерфейса, следует продумать, каким образом следует организовать взаимодействие графического кода с пользовательским интерфейсом; для этого существует несколько различных моделей. Для такого взаимодействия целесообразно использовать самый высокий из возможных уровней абстракции. Если вы генерируете статические изображения, то одним из приемлемых и концептуально несложных способов реализации указанного подхода может быть создание битового образа в памяти и его назначение свойству Image элемента управления PictureBox. Если требуется непрерывное обновление изображения, то приложение может создавать изображение во внеэкранном буфере и периодически копировать кадры на поверхность формы подобно кинопроектору. Пользовательские элементы управления особенно удобно использовать в тех случаях, когда требуется высокая степень интерактивности взаимодействия пользователя с создаваемой графикой, например, диаграммой, позволяющей переходить с одного уровня детализации данных, которые она представляет, на другой. Кроме того, пользовательские элементы управления могут генерировать пользовательские события, которые ваше приложение может перехватывать. Каждая из вышеперечисленных стратегий интеграции пользовательского интерфейса характеризуется своими видами взаимодействий, для которых она больше всего приспособлена; при этом очень важно явно сформулировать, какие именно задачи должна решать графика в мобильном приложении, и выбрать наиболее подходящую стратегию решения этих задач.