Мобильная веб-разработка: HTML5 приложение для Android
Вступление
К счастью, есть более чем один способ написать приложение для мобильного телефона. Можно сделать сайт, упаковать его специальным образом, и вуаля, вот вам и приложение! Именно такой подход предлагает нам проект phonegap.com именно об этом методе и пойдет речь в этой статье.
Уверен что ни стоит обсуждать экономическую целесообразность данного подхода. Она на лицо. Да, знаний нужно больше чем у среднестатистического веб разработчика, но все же, это сайт! Это понятно! Это тот же HTML, это тот же броузер, тот же Javascript. Найти разработчика ни так сложно, как скажем “нативного”. А уж если умножить на кроссплатформенность данного решения, так и вообще может показаться что это панацея. Конечно, мы то с вами знаем, что ни какой “пилюли” не существует, но в ряде случае, это действительно best practic
Итак, мое рабочее задание звучало так: Разработать клиентское приложение, под ОС Android. Приложение — игра. Квест. Суть игры заключается в следующем: группа людей, желающих интересно отдохнуть, делятся на команды. Каждой команде дается по смартфону. В смартфоне приложение. Открываем приложение. Приложение соединяется с сервером и оттуда приходят вопросы. Для каждой команды они свои. Вопросы могут выглядеть как обычные вопросы с вариантами ответов, ну скажем Сколько лет городу Санкт-Петербург?, так и вопросы локации. Найдите парадный вход в инженерный замок. Команда двигается, находит вход, нажимает Мы на месте и координаты уходят на сервер. От сервера ответ, верно или нет. Есть также вопросы фотографии. Например Сфотографируйте себя на фоне инженерного замка. В сумме, все ответы оцениваются и в итоге одна из команд выигрывает, набирая больше очков. Вкратце все.
Шаг 1 — протитипы
В общем задание нам понятно. Предположим что техническое задание уже составлено. Что еще? Нужны прототипы. Вот они:
Шаг 2 — макеты
Следующий шаг. Нужно их от рисовать. Беремся за работу, получается следующее.
Шаг 3 — выбираем фреймворк
Возьмем Sencha Touch. Фреймворк сделан на подобие ExtJS. Большое количество классов. Компонуем их, настраиваем — получаем приложение. Доступ к HTML элементам есть, но на уровне фреймворка управлять элементами крайне не разумно. Грубо говоря, поменять стандартное визуальное отображение элементов крайне затруднительно. Зато данные от сервера получать в формате JSON одно удовольствие.
И наоборот. Jquerymobile это доступ к элементам, по сути расширенный Jquery. Добавляются теги к элементам. После загрузки фреймворк по этим тегам дополняет элементы стилями и другими элементами. Вот только подружить фрейморк с JSON данными от сервера у меня не получилось. Jquerymobile ждет от сервера html код. Безусловно можно получать JSON и его на стороне клиента преобразовывать в html код, что собственно и делает Sencha. Но это ни есть хорошая практика. Это идет в разрез с идеологией фреймворка. Возникает огромное количество проблем, решить которые крайне сложно.
Стоп. А зачем нам фреймворк? Что первый, что второй, по сути, это, так сказать, готовая элементная база, готовые решения, цель которых помочь вам сделать приложение (сайт) визуально похожим на нативное приложение. А нужно нам это? Нет. А как же PhoneGap? А что он, ему все равно, что вы используете. Ни где ни каких ограничений нет. Ну тогда давайте просто сверстаем приложение, как обычный сайт и дело с концом!
Шаг 4 — верстаем
Сам процесс верстки ни чем ни отличается от стандартного. Есть безусловно нюансы, вот о них и поговорим. Первым таким нюансом являются метатеги.
Без этой строчки в заголовке html кода, ваше приложение будет отображаться как обычный сайт. Броузер будет его зумировать, что реалистичности приложению совсем не добавляет.
В отличии от десктоп броузера, броузер мобильного телефона (вероятно ни всех) добавляет рамку к элементам, на которых установлен фокус. Подобная рамка, при наведении фокуса, есть по умолчанию в Google Chrome, в момент когда мы вводим данные в очередное поле . Лечится это аналогично.
И самый последний нюанс это position:fixed. И это действительно проблема, ибо универсальных решений тут нет. Все упирается в сами мобильные броузеры, они просто не поддерживают, или поддерживают но не полностью, такой функционал. Ни получается закрепить панели управления одним решением для всех случаев. К примеру, jquerymobile, до версии 1.1, в случае если броузер не поддерживает position: fixed, эмулировал скроллирование и динамически менял позицию закреплённых элементов, что в общем-то не придавала реалистичности и порой выглядело “ни айс”.
Вот по этой ссылке есть описание мобильных броузеров, которые поддерживают position: fixed
bradfrostweb.com/blog/mobile/fixed-position
а также есть ссылки на Javascript библиотеки, которые эмулируют работу position: fixed и процесса скроллирования. К сожалению работу ни одного из них удовлетворительной назвать нельзя.
В моем конкретном случае, мобильная платформа была указана как Android 2.3, а она поддерживает position: fixed, но при этом пользовательский zoom работать не будет, что по сути в приложении ни к чему. Указываем в заголовке viewport
И прописываем стили
Шаг 5 — эмуляторы
Очевидно, что верстать и смотреть в броузере, в окне монитора, затруднительно. Разрешение андроид приложение, скажем 320×480, а какие размеры экрана у вашего монитора? На помощь приходят эмуляторы. Самый простой эмулятор уже есть в вашем броузере! Если вы загрузите сверстанные страницы в Google Chrome и нажмете Ctrl+Shift+I, броузер покажет вам инструменты разработчика. В правом нижнем углу вы можете найти иконку с шестеренкой, нажимайте на нее. Далее выбираем вкладку Override и вот он, ваш эмулятор. Выбираем User Agent и ставим галочку Device Metric. На первом этапе этого будет достаточно.
А еще есть эмулятор от самого PhoneGap! emulate.phonegap.com
Называется Ripple. Ставится в виде дополнений к Google Chrome. Ура! Наши возможности резко увеличились. В случае, если в своем приложении вы используете библиотеку cordova для расширения функционала приложения, скажем для работы с камерой телефона или компасом, то Ripple даст вам возможность симулировать данные процессы.
Ну и раз пошла речь про эмуляторы, нельзя ни сказать и про эмулятор, который ставиться вместе с Eclipse, если следовать инструкции от Phonegap
docs.phonegap.com/en/2.2.0/guide_getting-started_android_index.md.html#Getting%20Started%20with%20Android
Этот эмулятор уже ведет себя совсем как настоящее устройство. Все ошибки, какие были найдены на этом эмуляторе, все аналогичным образом были найдены и на устройстве. Ну и конечно нужно сказать, что пользоваться этим эмулятором оперативно сложно. Долго грузится, трудно текст набирать и т.д. Подходит он для самой последней стадии. Когда ваше приложение уже работает прекрасно на всех других ранее перечисленных эмуляторах.
Шаг 6 — программируем
Хоть статья и для программистов, размешать весь код тут просто глупо. Опишу в общем. Программирование веб приложение, по сути, ни отличается от программирование небольшого сайта. Тут те же методы и подходы, но выполнены на Javascript. Тот же MVC, те же паттерны: синглетон, компановщик и т.д.
Вот фронт контроллер
* В javascript нет магических методов. Если скажем в PHP мы можем использовать __call, и вызывать App.SomeSome(‘ ’), то тут нужно будем писать App.Run(‘SomeSome’, ‘ ’)
Вот пример контроллера:
Вот небольшой пример модели
Вот пример представления
По сути, тут тоже самое, что и в случае, если бы сайт писался на PHP. За исключением фундаментального принципа, Javascript — асинхронный язык и без callback тут ни как (если не использовать специальные библиотеки конечно же)
Отдельно хочется остановится на нюансах, а именно работа с фотокамерой смартфона. Из коробки javascript не умеет этого делать. На помощь приходит библиотека Cordova, которую предлагает подключить PhoneGap. А вот ссылка, на описание работы с камерой телефона
При работе с расширенными функциями Javascript и в частности с камерой, я ждал от них больше всего проблем. И не напрасно. Первое, с чем пришлось столкнутся, это с тем, что после фото съемки, камера просто показывала черный экран и не возвращалась обратно в приложение. Как оказалось, это связано с тем, что по умолчанию фотография делалась максимального качества и файл получался большой. Процесс его переноса в приложение, в следствие не большой мощности самого телефона, занимает существенное время. Пришлось внести изменения в демонстрационный код
Но и это оказалось еще не все. Метод getPicture возращает base64 закодированную картинку, а вот данные между сервером и клиентом передаются в виде запросов JSONP.
Очевидно что передать такое количество данных через GET запрос невозможно. Серверная часть, кстати, не помню говорил я или нет, на PHP. Да, не самое лучшее решение, про WebSocket можно забыть. Проксирование тоже не сделать. Вероятно, решение данной проблемы была одна из самых сложных. А решение нашлось следующее. Время идет и стандартные классы расширяются, добавляются новые методы. Так вот класс XMLHttpRequest обзавелся новыми событиями. Кроме стандартного onreadystatechange появилось также событие onload. Если обработчик ответа от сервера “повешать” на него, и в заголовке Content-Type указать application/x-form-urlencoded, то броузер будет делать кроссдоменный запрос методом POST, что, собственно нам и нужно. Вот пример
И еще, очень важный момент. Кроссдоменный запрос, не важно как он реализован, является синхронным, даже не смотря на то, что выше приведенный код выглядит как асинхронный.
Столкнулся я также и с проблемой Same Origin Policy. Решение этой проблемы лежит на серверной стороне. В конфигурационных файлах прописывается разрешение на кросс доменный запрос и дело с концом.
Хочется также отметить, что в случае, если вам не нужны расширенные функции работы с телефоном: акселерометр, компас, камера, медиа и т.д. подключать библиотеку cordova не обязательно (а это примерно 300 килобайт). Геолокация, кстати, доступна и без нее.
Шаг 7 — отлаживаем
Вот наше приложение готово. Сверстано и прекрасно работает на эмуляторе Ripple (см. раздел про эмуляторы). Начинается самое интересное, а именно отладка на телефоне. Но сначала, попробуем запустить приложение на эмуляторе, в eclipse. Перед каждым запуском приложения на эмуляторе, система просит отчистить проект. Project -> Clean. Не забываем это делать. Нажимаем Run — поехали!
После загрузки эмулятора, в панели LogCat Eclipse будет огромное количество сообщений. Первым вопрос который возникает — какие наши? Для того, чтобы видеть только свои ошибки, и в частности, видеть сообщения которые приложение выводит в консоль console.log, нужно настроить фильтр. В панели LogCat, слева, есть отдельный блок, Saved Filters. Открыв ее, вы конечно увидите пустой список, ибо фильтров у нас пока нет. Нажимаем на плюсик и видим окно
Вводим в Log Tag web console, как на картинке и теперь Log консоль будет показывать сообщения от вашего веб приложения.
Как и ожидалось, эмулятор в броузере, далеко не то что эмулятор в Eclipse. Действительно, появились ошибки, которых ранее не было.
Начинаем изучать ошибку. Очевидно что ошибка вызывается в момент получения данных с сервером. Ошибка говорит что приходит статус 0. Начинаем искать решение в Google, и вот что находим
simonmacdonald.blogspot.ru/2011/12/on-third-day-of-phonegapping-getting.html
stackoverflow.com/questions/11230685/phonegap-android-status-0-returned-from-webservice
Делаем вывод: вероятно нужно добавить статус 0, как верный статус, для продолжения обработки ответа сервера. Ищем, где же это сообщения JSCallback и находим его в файле cordova.js на строке 3740 (cordova-2.1.0.js)
Пробуем заменить if (xmlhttp.status === 200) на if (xmlhttp.status === 200 || xmlhttp.status === 0) и вуаля — ни какого эффекта!
Дальше не буду рассказывать как я потратил целый день, кружа вокруг этой ошибки. Скажу только, что был готов отчаяться, ибо ни что не могло мне помочь. Приложение все равно падало, пока я просто не решил закомментировать часть кода. И о чудо! Ошибка исчезла! Возвращая, по частям, свой код, я нашел его часть, которая приводила к ошибке.
Почему смена Хеша, приводила к такой ошибке, для меня осталось загадкой. Если у кого какие будут мысли на этот счет — велком.
Шаг 8 — запускаем
Чтобы запустить приложение уже не посредственно на телефоне, достаточно войти в решим настройки, выбрать раздел Разработка и там взвести галочку напротив пункта Отладка USB. Далее, нажимая RUN в eclipse, среда определит что у вас подключен телефон к USB, а я надеюсь вы уже это сделали, и начнет запускать приложение уже на аппарате.
Источник
Разработка HTML5 игры под Android с нуля и до релиза
Вместо вступления
Потратив несколько суток подряд (без перерыва на сон) на изучение поддержки HTML5 всеми любимыми Android-гаджетами, решил, что данной теме стоит уделить внимание. В статье постараюсь раскрыть по шагам все этапы (конечно же базовые/ключевые/основные) создания HTML5 Игрового приложения для Android от идеи до релиза самого APK файла. Возможно, ничего нового я и не открою маститым разработчикам, но для новичков постараюсь описать все как можно проще, со скриншотами и пояснениями.
Желающих узнать подробнее приглашаю под кат.
Вообще много можно говорить о потенциале Android, о развитии HTML5 и об их взаимодействии. Я этого делать не буду. Так что, сразу к делу.
Идея создания игры под Android наверняка заседает в разумах десятков сотен разработчиков, и тех, кто себя таковыми считает. Я не исключение.
Весь процесс будет разбит на несколько шагов а итоговое приложение будет состоять из двух частей:
— Обертка (в данном случае для Android)
— Игра
Шаг 1. Написание самой игры
Еще одним плюсом написания игры на HTML5 является тот факт, что для тестирования не требуется куча запущенных программ, IDE, эмуляторов и так далее. Нужен лишь браузер (в моем случае это Chromium) и текстовый редактор (BlueFish)
Игра будет несложной: есть синий прямоугольник и есть зеленый прямоугольник. Задача игрока — перетащить синий прямоугольник на зеленый в обход красного, который перемещается по игровому полю в произвольном направлении.
Для разработки игры буду использовать J2ds (игровой движок).
Код готовой игры:
На качество кода игры внимания можно не обращать, ибо не это цель статьи. Хотя конечно, можно оптимизировать сколько угодно, этот процесс вообще наверное бесконечен.
Шаг 2. Android Studio. Создание обертки для игры
Я не собираюсь ни с кем мериться крутостью той или иной IDE для разработки под Android, а покажу на примере Android Studio. Для работы нам потребуется:
— Java машина (под мою Linux подходит OpenJDK);
— Дистрибутив Android Studio.
Как только все установите (Этих двух программ достаточно), запускайте Android Studio.
Откроется стартовое окно (если первый запуск), если не первый — то откроется сама IDE, но сути не меняет, пройдем в SDK Manager:
Тут нужно галочками отметить необходимые вам версии Android, с которыми вы будете работать, в моем случае это Android 4.4.2, вы можете выбрать хоть все сразу.
Главное — выберете обязательно «Tools» и «Extras» и нажимайте «install packages».
Как только у вас все скачалось, запустится IDE с унылым серым фоном и несколькими кнопками, жмем первую и создаем новый проект. Если IDE запустилась сразу в рабочем состоянии, то: «File->New->New Project»
Заполняем необходимые поля, и жмем Next
Выбираем нужную версию андроида и Next
Тут выбираем Blank Activity (пустой шаблон с Hello, World!)
В следующем окне заполняем данные для создания классов, я менять не буду для наглядности:
Торжественно жмем Finich и ждем, пока IDE все сконфигурирует и подготовит для работы.
Откроется окно с дизайнером форм. Оно не такое, как в Lazarus, Delphi, но что-то схожее все равно имеется:
Не спешите ничего менять или что-то щелкать, настройка еще не окончена. Открываем «Tolls->Android->AVD Manager» для настройки эмулятора.
Тут, если ничего нет, жмем «Create Virtual Device», если есть, можете не создавать новый, у меня уже был, т.к. я «натыкал» его, пока разбирался. Если же вам нужно создать новый эмулятор, то там все просто:
1. Выбираем размер экрана и модель телефона
2. Выбираем версию андроида (у меня 4.4.2)
3. Настраиваем устройство.
На третьем шаге подробнее:
Т.К. игра у нас вытянута по горизонтали, выбрать нужно ландшафтный режим.
Когда все настройки введены, жмем на зеленый треугольник и запускаем эмулятор. После запуска ждем, когда устройство полностью загрузится и запустится ОС:
Это окно не закрывайте, в нем будет происходить эмуляция. Теперь можно вернуться в редактор, и изменить ориентацию в дизайнере форм:
Можно запускать! Вот теперь точно можно.
Если появится запрос на выбор эмулятора — то можно поставить галочку внизу:
Мои поздравления! Все работает, проверено!
Сворачиваем наш эмулятор (Но не закрываем!) и переходим в редактор, Там все немного сложнее (чуть-чуть).
Переключиться нужно в режим «Text». У вас в activity_main описаны все элементы, которые есть на форме. Включая саму форму. Да и не форма это вовсе.
Т.к. мы делаем игру в HTML5, а тут у нас только обертка для игры, удаляем весь текст и вставляем следующее:
Теперь, если опять переключиться на дизайн, то выглядеть будет иначе:
Как видно, теперь вместо «Hello, World» во всю красуется растянутый на весь экран — WebView. Этот объект и является нашим «окном» в игровой мир.
Можете запустить даже, посмотреть, будет белый экран. Идем дальше.
А дальше нам нужно перейти в наш проект, для этого слева открываем поле «Project» и выбираем вкладку «Android», если не выбрана:
В этой вкладке представлена структура проекта и все его внутренние файлы и ресурсы.
Пришло время поработать над функционалом нашего «браузера», ведь это именно он! Открываем класс «MainActivity.java» и удаляем все лишнее, оставив только основное:
Если не забыли, мы в файле activity_main добавили WebView, обратите внимание на выделенную жирным строчку:
Нам нужно объявить объект класса WebView.
Для этого к списку импортов дописываем:
А затем объявляем наш объект myWeb внутри класса MainActivity:
Теперь, после строчки setContentView(R.layout.activity_main); вставляем следующий код:
Вот что получилось у меня в редакторе:
А вот, что в эмуляторе:
Если у вас так же — мы на верном пути!
Осталось дело за небольшим:
Там, где мы подгружаем страницу нашему браузеру, путь к файлу выглядит так: «file:///android_asset/index.html»
Следует учесть, что любые файлы мы можем хранить внутри нашей игры, имея к ним доступ.
В нашем случае ключевая папка: «android_asset», давайте ее создадим (да, по умолчанию ее нет в проекте):
«File -> New -> Folder -> Assets folder», откроется окно где достаточно просто согласиться с IDE.
Заметили? В проекте появилась новая папка:
Жмем по ней правой кнопкой мыши -> «Show in Files», откроется системный проводник (в моем случае Nautilus), обратите внимание на путь к папке. Имейте так же ввиду, что папка называется «assets», но доступ к ней идет через «android_asset».
Дальше все совсем просто — копируем нашу игру в папку assets:
Файл index.html — это тот самый index из начала этой статьи. Ну что, пробуем запустить!
Небольшой совет: тестировать лучше всего на реальном устройстве посредством USB, так результаты теста будут нагляднее, да и управлять мышью не самый удобный вариант, не говоря уже о множественном нажатии.
Шаг 3. Android Studio. Сборка приложения и его подписывание
Когда игра вами полностью отлажена (в браузере или на эмуляторе), обертка полностью готова и все этапы разработки позади, можно собирать приложение. Android Studio позволяет собирать приложения и подписывать их вашими ключами.
Для создания ключей в этой IDE есть специальная утилита «KeyTool».
Переходим к созданию исполняемого файла приложения («Build -> Generate Signed APK»):
Если ранее ключей и алиасов вы не создавали, нажимайте «Create New». Заполнить поля можете на свое усмотрение, достоверность данных целиком лежит на вас.
Первое поле — это путь к папке, в которую будет сохранен ключ. Форма после нажатия Ok заполнится автоматически:
Для последующих приложений создавать новые ключи не обязательно, вы можете подписывать вашим ключем и другие приложения, именно для этого и есть кнопка «Choose Existing».
На следующем шаге IDE попросит у вас еще раз ввести пароль, а затем указать папку для сохранения APK файла.
Теперь можете расслабиться и попить, к примеру, кофе.Система начала компиляцию, результат в статусбаре:
После того, как компиляция завершится, система вам об этом сообщит.
Теперь достаточно переместить файл на телефон / планшет и установить, как обычное приложение.
Источник