Android scripting with javascript

12 часов в шкуре Android разработчика глазами JS разработчика

Все началось с Kotlin. Случайно попалась статья про новый язык, что на нем можно писать под Android. Соприкоснувшись с темой, узнал что изначально приложения под Android пишутся на JAVA. Решил узнать на сколько трудоемко писать приложения под Android, в чем преимущества платформы на практике. Ведь по сути приложения JS и приложения Android выполняют одну и туже функцию. Заодно решил провести эксперимент. Что можно сделать за 12 часов, не зная что такое JAVA и тонкости разработки под Android, используя как помощник только Google. Пришла идея, которую развил в постановку задачи.

Постановка задачи

Взять из внешнего сервиса список всех Аэропортов мира и по коду Аэропорта получить от внешнего сервиса он-лайн табло с информацией о статусах рейсов. В 100% приложений, которые лежат в google play и реализуют такую функцию, нужно проходить цепочку действий, искать внутри приложения. Я лично, не нашел агрегатор, который позволял бы на первой странице ввести любой Аэропорт и получить его он-лайн табло. Идея и приложение само по себе простое, но это функция которой пользуется любой кто совершает перелет. Доступ к такой информации должен быть мгновенным.

Нашел потрясающий сервис, который открывает много возможности в части разработки под Авиацию. developer.flightstats.com Зарегистрировался получил на месяц бесплатный аккаунт.

Действовал интуитивно, полагаясь на свой опыт разработки в JavaScript. Набросал скетчи экранов в Photoshop. Составил требования к приложению.

Форма «Поиск»

Форма «Результат»

  • Вывод данных в виде таблицы
  • Сортировка по времени Прилет\Вылет

Разработка

Дальше был Я, Google и Android Studio.

Из опыта понимаю что код нужно организовывать. Интуитивно определил структуру проекта. Выделил следующие группы(Models, Stores, Views, Fields, API, Adapters) Двигало мной в этот момент бессознательное, вернее опыт. Дальше начал развлекаться с Layouts. Android Studio очень интуитивный редактор, это одна из причин которая подвигла попробовать написать Android приложение. Если kind of intellij idea – значит все комфортно. Плюс редактор лежит в бесплатном доступе, никаких ограничений, развивается и обновляется регулярно. Layouts сложились на раз два. Ни одного глюка за весь период работы, все на своих местах.

Момент который меня насторожил в самом начале, в 90% источниках, поиск и работа ведется по ID компонента. Обще принято, работа с ID это bad practice, в Android оказалось нормальной практикой. Погуглил, одно из лекарств DataBinding, отличная вещь, позволяет уйти от findViewById. Но, принцип в начальной стадии и еще год назад связь работала в одну сторону. Звучит странно, DataBinding но в одну сторону. Нужно было писать свою реализацию чтобы DataBinding был полноценный. Опираясь на реализации в JS, удивил концепт, который на текущий момент предлагает Data Binding Library(можно увидеть в большинстве случаев в сети), в ViewModel размещается логика по обработке handlers от визуальных компонент, которые в свою очередь могут иметь прямой доступ к данным которые лежат в ViewModel. С виду какой то гибрид контроллера и ViewModel.

Далее пошли вопросы коммуникации, то что нагуглилось с первого раза повергло в шок. Чтобы сделать обычный AJAX запрос нужно было тянуть строк 70 кода. Создавать фоновый процесс и там уже творить магию соединения, а потом через буфер собирать ответ. «Не может быть, чтобы было так сложно!» и продолжил поиск. В одном из результатов попалась статья про Retrofit2. С Retrofit стало все веселее и в целом жить можно в части коммуникаций. Определился с интерфейсами взаимодействия с сервером и начал сопрягать данные с визуальными компонентами.

С фильтром spinner(он же combobox) пришлось повозиться, возможно из-за неопытности. По ходу возникала куча вопросов от конвертации одного типа в другой до как реализован ООП в JAVA, но все элементарно находилось в stack overflow с ответами и примерами, плюс интуиция. В целом все шло как по маслу, кроме некоторых моментов. Чего не ожидал, что получу головную боль с датой. Почему то JAVA(или может быть это у меня так вышло) по defaul выдавала все в UTC.

В целом каких то совсем непреодолимых моментов не было из-за которых возникал полный стопор. Что не понял(зачем это сделали как dafault поведение?!) При изменении ориентации экрана(или конфигурации), ваша View которая присутствует на экране уничтожается и в новом повернутом экране заново пересоздается(фоном идет масштабная работа). Что порождает головную боль если у Вас в классе View(она же «Активность») есть динамические данные, они просто теряются при уничтожении View и с этим что-то надо делать. Дайте эту возможность, но опционально, для тех кто хочет подменять экраны при повороте. Интересно услышать мнение Android разработчика по этому поводу, возможно я не вижу всей картинки в целом.

Awesome

Потрясла производительность интерфейсов при большой нагрузке. Для теста сделал 8 spinner, в каждый забросил 4000 записей(в каждой записи еще набор свойств) и приложение даже не крякнуло. При такой ситуации, JS приложение напряглось бы, и если бы еще нужно было отображать все записи сразу, и иметь доступ работы с ними, то большая вероятность поймать зависание экрана или вообще «Опаньки». Пришлось бы тащить буферизацию вывода или решать как то алгоритмически. Но есть задачи когда нужен весь объем и сразу.

Многопоточность и фоновые процессы, на лету. Что в JS нужно можно делать с помощью webworkers, но там свои трудности, которые при разработке под Android решаются на раз, два. Причем фоном можно тягать действительно весомые объемы. Это огромное value для разработки off line приложений с сложными инженерными расчетами.

Читайте также:  Не включается андроид идет загрузка

Приложение под браузер имеет свой потолок по производительности, если речь идет о высоко нагруженных интерфейсах(вывод одновременно большого объема данных) или когда фоном нужно делать объемные вычисления. Здесь перед Android приложениями снимаю шляпу. Но если Вам нужно делать что-то средне статистическое, то javascript возьмет свое скоростью разработки.

Резюме

Признаю, трудоемко писать под Android и требует в разы больше времени чем написание приложений на JS, но google интенсивно развивает и наращивает платформу. Неделя сидения за книгами и теорией Android разработки скорее всего убило бы идею попробовать сделать Android приложение и не дала бы навыков и опыта полученного за эти 12 часов. Реально столкнуться с проблемами и увидеть мир изнутри, получить первую оценку возможностей Android приложений и в будущем, столкнувшись с задачами трудно реализуемыми в JS, иметь в запасе знания куда можно еще бросить свой взгляд. Практика — быстрый путь к достижению навыков и опыта.

Что получилось: Android-приложение для просмотра он-лайн табло любого аэропорта мира.

Источник

JavaScript to APK. Подводные камни разработки под Android для тех, кого задолбал PhoneGap. Построение мостов из Java в JavaScript

Я люблю игры на JavaScript и стараюсь сделать их код пуленепробиваемыми для портирования на все платформы. Полгода назад я уже писал о сборке Android приложений и сегодня хотел бы раскрыть тему более подробно.

Сразу предупрежу, что мне пришлось отказаться от PhoneGap, т.к. опыт использования его в двух проектах меня огорчил. Он отлично справляется с «Hello World» приложениями, но при конвейерной сборке всего подряд всплывают нюансы.

Почему PhoneGap не пошел:
1. Он изначально пустой. Постоянно приходится подключать все новые и новые модули.
2. Многие модули написаны криво. Они либо берут много лишнего, либо ведут себя неожиданно. Например, из двух модулей под Android для отправки SMS, один не работал, второй — отправлял true при любых условиях.
3. Не решены элементарные вещи, вроде получения EMEI телефона. Нужно постоянно допиливать.

Я так и не понял сути PhoneGap. Изначально ожидал одну кнопку «сделать хорошо», а не деле он ничего не делает. Под каждую платформу мне все равно надо ставить SDK. Под каждую задачу — искать и ставить модуль. Сами модули тоже ограничены. Они могут делать что-то только под часть платформ, а если нужно под другие — то приходится снова искать модули, которые смогу сделать это на других девайсах. Много мусора и ненужных вещей, а ведь хочется собирать билды с минимумом затрат. Все эти факторы заставляют писать нативно. И вот тут начинают вылезать подводные камни.

Почему CocoonJS не пошел:
С CocoonJS работал мало, поэтому никаких особых вопросов не возникло. Билды с canvas действительно работают быстрее. Но в общем — смысла работать с CocoonJS не увидел, т.к. он платный.

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

Перейдем к сути

Для начала начнем с основы — WebView с запущенной HTML страничкой на весь экран. В onCreate MainActivity пишем:

Все спорные ситуации будем решать в Java. Помните, пишите вы для Bada или SmartTV — всегда есть какой-то стандартный функционал, который позволяет кидать мосты в JavaScript. В нашем случае для Android`а мы кинули экземпляр класса WebAppInterface, а сам класс будет выглядеть так:

Подводный камень: Работа с такими мостами обычно может быть асинхронна или непредсказуема и полна сюрпризов.

Если у вас возникла необходимость из Java сообщить JavaScript`у какое-либо событие на ровном месте, самый простой способ достучаться до него — это стучать в URL:

Подводный камень: В Android`ах > 4 от Samsung`а при тач-событии DOM элементы могут подсвечиваться синим цветом.

Обратите внимание на этот нюанс. Типичная «защита» вам не поможет:

Чтобы обойти багу, надо добавить:

Но это не всегда решает проблему. Возможно, на проблему влияет сама верстка. Например, возьмем два приложения: Судоку и Тест. В судоку доска сверстана таблицей, и для таблицы такое решение помогло. В Тесте же кнопки это. Вроде бы все по стандартам семантики HTML5, и все должно быть более чем прекрасно, но на деле приходиться добивать таким CSS комбо:

Так же заметил, что синее выделение не появляется, если тач-событие пришлось точно на текст кнопки (текст при этом должен быть очень большим).

Источник

Shell-скриптинг в среде Android

Содержание статьи

Android основан на ядре Linux, включает в себя набор стандартных UNIX-команд и простой шелл sh. Все это значит, что мы можем не только использовать командную строку для выполнения низкоуровневых операций, но и писать шелл-скрипты, которые будут выполнять функции, недоступные из графического интерфейса. В этой статье мы поговорим о том, что с их помощью можно сделать и зачем все это нужно.

Для прошлого номера журнала я написал статью о Tasker — системе, которая позволяет автоматизировать работу Android и заменить сотни сторонних приложений. К сожалению, Tasker ограничен высокоуровневыми функциями Android и не позволяет выполнять такие низкоуровневые операции, как монтирование файловых систем, изменение параметров ядра, системных переменных или запуск демонов. Зато все это можно сделать с помощью скриптов.

Сразу оговорюсь, что в этой статье речь пойдет о шелл-скриптах в традиционном для Linux понимании, без использования инструментов вроде SL4A, QPython или Roboto. Главное назначение таких скриптов — изменение поведения системы, параметров ядра, работа с демонами (ADB, например) и тому подобное. Скрипты могут стартовать на этапе загрузки ОС, установки новой прошивки, после тапа по кнопке или же по традиции — из терминала.

В статье я расскажу, как писать такие скрипты, как заставить их стартовать автоматически, привязывать к определенному системному событию. В качестве бонуса также объясню, как заставить консоль восстановления (recovery) выполнить необходимые тебе действия перед установкой или сразу после установки новой прошивки. Начинаем.

Читайте также:  Build android apps on android device

Особенности Android-окружения

В самой своей основе, там, где нет Java и Dalvik, Android представляет собой минималистичный Linux-дистрибутив со всеми свойственными ему атрибутами: ядром, системой инициализации, набором библиотек, демонов, консольных команд и, конечно же, шеллом. Последний — это не что иное, как mksh из MirBSD, переименованный в sh; простой командный интерпретатор с поддержкой языковых конструкций классического Bourne shell из UNIX и автодополнением по нажатию Tab.

В качестве комплекта базовых UNIX-команд здесь используется toolbox, своего рода урезанная альтернатива BusyBox, которая позволяет вызывать несколько разных команд из одного бинарника (с помощью симлинков). Toolbox включает в себя очень ограниченный набор команд, в котором нет не только grep или sort, но даже cp. Поэтому для полноценной работы со скриптами настоятельно рекомендуется установка BusyBox, благо в маркете полно бесплатных инсталляторов.

Сам шелл располагается не совсем по адресу, поэтому «шибанг» в скриптах будет выглядеть несколько по-иному, а именно #!/system/bin/sh. Зато о расположении бинарников можно не думать вообще, так как в переменной $PATH всегда прописаны правильные значения. Каталогов для поиска команд тут всегда три: /system/bin/, /system/sbin/ и /system/xbin/ для внешних бинарников. Туда обычно устанавливается BusyBox.

Основное назначение скриптинга в Android — работа с ядром и системными утилитами. Ядро тут стандартное и экспортирует все те же интерфейсы /proc и /sys, через которые можно рулить железом и состоянием системы. Плюс есть набор специфичных для Android утилит, которые будут очень полезны при разработке скриптов:

  • pm — менеджер пакетов, позволяет устанавливать, удалять и перемещать софт;
  • am — менеджер активностей (Activity), может быть использован для запуска приложений;
  • dumpsys — дамп в консоль массы различной информации о состоянии системы;
  • screencap — утилита для снятия скриншота;
  • screenrecord — утилита для записи скринкастов;
  • getprop/setprop — команды для чтения и изменения системных переменных;
  • start/stop — запуск и остановка системных служб;
  • input — позволяет отправлять в текущее окно кей-коды (эмуляция клавиатуры);
  • service — утилита для управления Java-сервисами, имеет очень много возможностей;
  • svc — позволяет управлять Wi-Fi, USB-подключением и питанием.

Часть вывода команды dumpsys

Хакер #185. Докажи баг!

Первый пример

Теперь давайте попробуем написать первый скрипт. Делать это лучше на компе, а еще лучше в Linux или редакторе, который умеет создавать текстовые файлы без символа возврата каретки (который при открытии в Android будет выглядеть как ^M в конце каждой строки). Наш первый скрипт будет состоять всего из двух строк, которые делают бэкап всех установленных приложений на карту памяти. Его код (требует BusyBox):

Сохраняем (пусть он называется apk_backup.sh) и перекидываем на смартфон с помощью ADB:

Теперь его нужно запустить. Проще всего сделать это с помощью все того же ADB:

Примерно таким же образом скрипт можно запустить из консоли на самом смартфоне/планшете:

Само собой, такой способ не очень удобен. Поэтому нам нужен какой-то быстрый способ запуска скрипта. Наиболее удобное из найденных мной решений — это приложение QuickTerminal. Устанавливаем, запускаем, переходим на вкладку Quick Command, нажимаем кнопку «+», вбиваем имя (произвольное) и команду (sh /sdcard/apk_backup.sh), в поле Output Type выбираем либо Dialog Output, либо Nothing. В первом случае во время выполнения скрипта на экране появится окно с результатом, во втором все пройдет в фоне. Кому что удобнее. Далее сохраняем и получаем кнопку, с помощью которой скрипт можно будет запустить быстро и легко.

Теперь напишем скрипт, который восстановит наш бэкап:

В нем мы задействовали команду pm с опцией install и флагами -t и -r, которые заставляют систему устанавливать приложения, даже если они подписаны тестовым ключом или уже установлены. Также можно использовать флаг -s, который принуждает приложения к установке на карту памяти (если такая возможность есть), или -f — установка во внутреннюю память устройства.

Почти все команды Android имеют подробную справку

Имея рут, можно даже сделать бэкап настроек всех приложений с помощью копирования и архивации каталога /data/data/, однако восстановить его будет очень проблематично, так как в Android каждое приложение исполняется от имени созданного специально для него Linux-юзера и хранит настройки внутри каталога, принадлежащего этому пользователю. Проблема здесь в том, что идентификатор Linux-юзера для каждого приложения генерируется динамически, поэтому после восстановления бэкапа в заново установленной системе идентификаторы не будут совпадать и приложения не смогут прочитать свои настройки. Придется вручную выяснять ID юзера для каждого приложения и менять права доступа на каталоги с данными.

С другой стороны, мы можем использовать встроенный в Android Backup Manager, позволяющий сторонним приложениям использовать возможности системы для бэкапа и восстановления приложений и их данных. Управлять им можно из консоли (а значит, и с помощью скриптов), но сам по себе он никакого бэкапа не производит, а возлагает эту работу на сторонние приложения. Helium — одно из таких приложений. Если установить и настроить его, операцию бэкапа и восстановления можно будет заскриптовать. Например, следующий простой скрипт сделает резервную копию всех сторонних приложений:

Конструкция $ здесь нужна, чтобы обрезать слово «packages:», которое pm добавляет в начало имени каждого пакета. Чтобы восстановить бэкап, можно использовать либо тот же Helium, либо команду bmgr:

Автозапуск

«Это все круто, но скрипты должны запускаться сами», — скажешь ты и будешь абсолютно прав. Без автозапуска от скриптов толку мало, но это легко исправить, если воспользоваться все тем же Tasker. Он умеет запускать любые шелл-команды в ответ на любое событие. Чтобы воспользоваться этой функциональностью, достаточно создать новый профиль, выбрать событие (для бэкапа лучшим событием будет время), затем добавляем действие, выбираем Script -> Run Shell, вбиваем команду (sh /sdcard/script.sh), выбираем, если необходимо, файл для записи результата и включаем профиль.

Другой популярный способ автозапуска — это использование средств автоматического исполнения скриптов при загрузке в сторонних прошивках. Сегодня почти все сколько-нибудь известные кастомные прошивки умеют стартовать скрипты из каталога /system/etc/init.d/, а в стоке такую функциональность можно получить с помощью приложения Universal init.d из маркета. С последним, однако, надо быть осторожным, так как оно запускает скрипты не на раннем этапе загрузки, как это происходит в том же CyanogenMod, а уже после полной загрузки системы.

Читайте также:  Рейтинг 2 din автомагнитолы андроид с алиэкспресс

Итак, что мы можем поместить в автозагрузку? Например, скрипт запуска демона ADB в сетевом режиме:

Для подключения к нему с ПК набираем такую команду:

Также мы можем применить некоторые оптимизации подсистемы виртуальной памяти:

Ну или подогнать механизм lowmemorykiller (автоматическое убийство фоновых приложений при нехватке памяти) под наши нужды:

Ну и конечно же, автоматический выбор планировщика процессов:

Все это можно сделать с помощью специализированного софта, но зачем загружать систему дополнительным ПО, которое еще и будет висеть в фоне, когда можно обойтись несколькими простыми скриптами?

Как запустить скрипт с помощью Tasker

Запуск скриптов до и после установки прошивки

Почти каждый, кто устанавливает на свой гаджет стороннюю прошивку, также ставит поверх нее пакет с фирменными приложениями Google (gapps), который включает в себя маркет, YouTube, Gmail и другой софт. Каждый раз, когда происходит обновление прошивки, раздел /system, содержащий ее и gapps, полностью стирается, но приложения Google всегда остаются на месте. Это происходит потому, что, кроме всего прочего, gapps содержит в своем составе специальный скрипт, который размещается в каталоге /system/addon.d/ и запускается консолью восстановления до и после установки прошивки. Этот скрипт делает бэкап и восстановление приложений Google.

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

Скрипт удаляет рингтоны, уведомления, движок синтеза речи и несколько приложений. Все эти действия запускаются в ответ на передачу скрипту опции командной строки restore (это делает консоль восстановления после установки прошивки), однако также предусмотрены и варианты обработки таких опций, как backup, pre-backup, post-backup, pre-restore и post-restore. Здесь это просто заглушки, но если бы мы захотели сделать бэкап некоторых файлов и приложений перед установкой прошивки, мы могли бы добавить их в блок backup, как это сделано в скрипте /system/addon.d/70-gapps.sh:

Этот кусок скрипта прекрасно иллюстрирует, как сделать бэкап файлов. Ключевые элементы здесь: функция listfiles, которая при запуске выводит листинг файлов, и функция backupfile, которая является частью консоли восстановления (определена в файле /tmp/backuptool.functions). Она делает бэкап файлов в цикле.

Содержимое /system/addon.d/ в CyanogenMod 11 на Motorola Defy

Скрипт бэкапа приложений Google

По словам разработчика mksh, изначально пользовательские версии Android-смартфонов вообще не должны были иметь в своем составе шелл, но после выпуска смартфона для разработчиков HTC (T-Mobile) G1 он фактически стал стандартной частью системы.

Версии Android 2.3 и ниже вместо mksh использовали минималистичный шелл ash, который входит в базовый комплект всех BSD-систем.

Чтобы получить одни и те же скрипты на всех устройствах, можно использовать приложение DropSync или FolderSync (автоматическая синхронизация через Dropbox).

Что еще?

С помощью скриптов в Android можно сделать намного больше, чем бэкапы и настройка параметров системы. Вот, например, скрипт, который просыпается каждые десять минут и, если уровень заряда батареи стал меньше 30%, отключает Wi-Fi и Bluetooth:

Чтобы скрипт работал в фоне, достаточно вызвать его следующим образом:

А это скрипт, который позволяет быстро заполнять формы, требующие ввода имэйла и пароля (в приложениях и на веб-сайтах):

Запускать его можно разными способами. Либо перед запуском приложения, установив задержку:

Либо повесить на какое-то событие Tasker, например на взмах смартфоном. Другой вариант — использовать буфер обмена. В Android, чтобы вставить нужный текст в буфер обмена, достаточно выполнить такую команду:

Не ахти как удобно, зато работает. Как мы можем использовать такую функциональность? Например, сделать простенький скрипт clip.sh:

Соль в том, что скрипт можно вызывать через удаленный ADB либо вообще поместить в /system/etc/init.d/, заменив $1 на нужный текст. Так нужные нам данные всегда будут под рукой, а бесполезный на смартфоне механизм копирования/вставки получит хоть какое-то назначение. Консольные команды можно использовать и для более высокоуровневых операций, например позвонить по указанному номеру:

Или просто открыть окно номеронабирателя с нужным номером:

Примерно таким же образом можно отправить SMS:

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

Другие полезные при скриптинге команды:

  • Перезагрузка в режим recovery:
  • Мягкая перезагрузка (без перезапуска ядра):
  • Открыть нужное приложение (в данном примере — «Настройки»):
  • Открыть веб-страницу:
  • Сообщить приложениям о низком уровне заряда батареи (есть софт, который при этом снижает свою активность):
  • Изменить MAC-адрес:
  • Активировать вибратор:
  • Включить фонарик:
  • Проиграть файл (может не сработать):
  • Отключить указанное приложение (можно организовать цикл для отключения bloatware по списку):
  • Получить список приложений, которые имеют уведомления в строке состояния:
  • Оптимизировать внутренние базы данных с настройками (можно добавить скрипт в автозагрузку, требуется BusyBox):
  • Переключить Wi-Fi-тизеринг на основной интерфейс (нужно для обмана операторов, которые ограничивают скорость соединения при раздаче интернета по Wi-Fi):

Для «отлова» нажатий кнопок можно использовать команду getevent

Вместо выводов

Для кого-то все описанное в статье может показаться несколько надуманным. Дескать, все это можно сделать с помощью стандартного софта и Tasker. Но зачем использовать тяжелый Java-софт там, где нужное действие можно выполнить с помощью простенького скрипта, который не занимает лишней памяти и может быть легко перенесен на другое устройство? Скрипты удобны, просты, быстро отрабатывают и дают возможность тонкой настройки под себя.

Евгений Зобнин

Редактор рубрики X-Mobile. По совместительству сисадмин. Большой фанат Linux, Plan 9, гаджетов и древних видеоигр.

Источник

Оцените статью