Начиная осваивать разработку для любой платформы, ты обязательно сразу же наткнешься на множество с первого взгляда незаметных подводных камней. Большинство из них будут связаны с самим процессом кодинга: несостыковки в API, скрытые функции, ограничения, особый стиль программирования для платформы. Есть и камни, лежащие немного поодаль: тестирование и автоматическая оптимизация, создание клипарта и иконок, получение автоматических краш-репортов. Неопытные разработчики для Android рискуют отбить о них обе ноги.
В этой статье мы рассмотрим проблемы разработки для Android в контексте утилит и инструментов. Мы избавимся от необходимости подключать смартфон с помощью кабеля во время тестирования и отладки на устройстве, расщепим приложение на версии Lite и Pro, встроим в него механизм автоматической генерации и отсылки на сервер краш-репортов, автоматизируем тестирование, обфусцируем и оптимизируем код, а также за несколько минут создадим для приложения иконку и все необходимые ресурсы. Поехали.
Итак, ты набросал свое первое приложение, и пора его запустить и проверить на работоспособность. Для этого в комплекте Android SDK есть эмулятор. Долгое время его упрекали за медлительность, но с выпуском Android Studio 2.0 ситуация намного улучшилась - x86-версия эмулятора получила хардварное ускорение, так что теперь он работает быстрее реальных устройств. К тому же у него появился удобный графический интерфейс, с помощью которого можно симулировать звонки, СМС, изменять данные GPS и сбои в сети, то есть все, для чего раньше приходилось использовать инструменты командной строки.
Поэтому, если ты еще не обновился, настоятельно рекомендую это сделать, не говоря уже о переходе с Eclipse. И обязательно выбирать x86-версию эмулятора в AVD manager, ARM-версия не поддерживает хардварное ускорение.
Второй этап - тестирование на реальном устройстве. Здесь все просто: подключаешь смартфон по USB, устанавливаешь драйверы, включаешь режим отладки в настройках для разработчиков, после чего девайс появляется в списке доступных для установки приложения (рядом с эмулятором). Проблема только в том, что в данном случае устройство необходимо держать подключенным к ПК с помощью кабеля, а если это твой основной смартфон, на который поступают звонки и сообщения, то об удобстве говорить не приходится.
К счастью, Android Studio (а точнее, утилита ADB, которую он использует для связи с устройством) поддерживает работу по сети. Но данную функцию еще нужно активировать. Если у тебя рутованный смартфон, то тебе повезло: включить отладку по сети можно с помощью приложения WiFi ADB . Последовательность действий:
$ adb connect IP-адрес
Теперь, если попытаться собрать и запустить приложение, ты увидишь в списке устройств также и свой смартфон. Те, у кого нет root, могут перезапустить ADB в сетевом режиме, предварительно подключив его кабелем. Делается это так:
$ adb tcpip 5555
$ adb connect IP-адрес
IP-адрес можно узнать через настройки: «О телефоне (О планшете) → Общие сведения», пункт «IP-адрес».
Окей, твой накиданный за полчаса огрызок вроде бы работает, и настало время превратить его в настоящее приложение с красивым интерфейсом и виджетами для рабочего стола. На этом этапе тебе наверняка понадобятся внешние библиотеки, реализующие различные концепции интерфейса, паттерны программирования и связь с внешними сервисами. И если с последними все ясно (нужен SDK для Dropbox - открываешь портал для разработчиков и следуешь инструкциям), то с остальными уже сложнее. Где их искать и какие библиотеки лучше?
Наиболее полный каталог библиотек - это Android Arsenal . Там ты найдешь практически все, что тебе нужно. Доступны удобный поиск и сортировка по рейтингу, для каждой библиотеки есть инструкция, как ее подключить к своему проекту, в том числе с помощью стандартной для Android системы сборки Gradle: достаточно добавить репозиторий в файл build.gradle проекта и указать библиотеку в списке зависимостей.
Отличный список must have библиотек ты найдешь на этой странице . От себя добавлю, что на первых этапах стоит сразу изучить Dagger 2 , RxJava и Retrofit . Став продвинутым разработчиком, ты так или иначе придешь к использованию этих библиотек.
Наконец, спустя дни или недели у тебя начинает вырисовываться полноценное приложение. Вот только никакого графического материала нет до сих пор: иконка стандартная, в форме зеленого робота, вместо клипарта - заглушки. Очевидно, без графики соваться в маркеты бессмысленно, однако и платить за иконку для своего первого приложения тоже глупо. Что делать?
На самом деле иконку можно сгенерировать. Есть замечательный веб-сервис Android Asset Studio , с помощью которого буквально за пару минут ты получишь красивую иконку во всех возможных разрешениях. В качестве основы можно взять подготовленную тобой картинку, просто написать текст или, что лучше всего, выбрать из предоставленного сервисом клипарта. Также ты сможешь задать стиль иконки (круглая, квадратная, в стиле iOS…), цвет, настроить тени и другие параметры. В результате в твоем распоряжении появится архив ic_launcher.zip , который необходимо развернуть в каталог AndroidstudioProjects/ИМЯ_ПРИЛОЖЕНИЯ/app/src/main/res . Обязательно создай веб-иконку, нажав на кнопку «Generate web icon». Она тебе понадобится.
Тот же сервис позволяет создать иконки для ActionBar’а и строки состояния . Принцип примерно тот же, скажу лишь, что в строке состояния лучше всего смотрятся иконки с отступом от краев 15%.
Кроме того, тебе понадобится так называемая Feature Image. Это специальная картинка, которую Play Market и другие магазины приложений используют в качестве плашки в верхней части экрана (когда открываешь страницу приложения на смартфоне). Ее можно сгенерировать с помощью другого сервиса . Для оформления скриншотов можно использовать официальный сервис от Google . Он создает вокруг скриншота рамку смартфона.
Приложение готово, иконка есть, интерфейс удобный, код качественный. Настало время тестирования, и первое, что ты делаешь, - рассылаешь приложение друзьям и знакомым. Но вот незадача: у некоторых из них приложение падает, а у тебя все работает отлично, и повторить действия, приведшие к падению, ты не можешь. Что делать, просить друзей присылать тебе листинг logcat?
Нет, нам нужна система краш-репортинга. Таких существует огромное множество, и все они реализуют один и тот же принцип работы: к приложению подключается небольшая библиотека, которая в момент падения записывает стектрейс и другие данные о падении и отправляет их на сервер, а затем специальный веб-интерфейс формирует на их основе красивые и наглядные отчеты.
Одна из самых популярных таких систем - Fabric , однако я рекомендую посмотреть в сторону Splunk MINT: он бесплатный, простой и легко интегрируется в приложение (достаточно добавить всего одну строку кода). Чтобы начать им пользоваться, необходимо подключить к проекту SDK, сделать это можно с помощью все того же Gradle. Открываем файл build.gradle (тот, что относится к приложению, а не ко всему проекту) и добавляем следующие строки:
Repositories { maven { url "https://mint.splunk.com/gradle/" } } dependencies { compile "com.splunk.mint:mint:5.0.0" }
После этого Splunk MINT покажет тебе строку кода, которую необходимо вставить в код:
Подписка позволит тебе в течение указанного срока читать ВСЕ платные материалы сайта. Мы принимаем оплату банковскими картами, электронными деньгами и переводами со счетов мобильных операторов.
Некоторое время назад официальной IDE для Android был Eclipse (как стандарт де-факто для Java) с плагином ADT. Некоторое время спустя среди Java-программистов начала набирать популярность IDE от JetBrains, потом для нее появился плагин для разработки под Android, и народ начал потихоньку переходить на нее с Eclipse.
Еще чуть позже Google объявляет о том, что будет делать Android Studio на базе IDEA. И вот на подходе уже вторая версия Android Studio, и Eclipse вспоминается разве что как страшный сон:)
Android Studio — официальная среда разработки под Android. По сути, Android Studio — это известная Java IDE IntelliJ IDEA с плагинами.
На данный момент существуют следующие опции при выборе IDE для Android:
В первую очередь, нужно убедиться, что у вас установлен JDK (Java Development Kit). Это обязательный компонент для разработки на Java, а поскольку разработка под Android ведется на Java — то и для разработки под Android тоже.
Во-вторых , поставьте галочки «show line numbers» и «show method separators»:
Первая будет отображать номера строк слева от текста, вторая — будет рисовать разделители между методами в коде.
Эти две опции невероятно важны, а особенно для новичков, и я не понимаю, почему они выключены по-умолчанию.
В-третьих , настройте автодополнение. Для этого в «Case sensitive completion» выберите «None»:
Поясню, почему именно так. Опция по-умолчанию подразумевает срабатывание автодополнения только в том случае, если первая буква набрана в правильном регистре. Опция None будет вызывать автодополнение независимо от того, в каком регистре вы начали набирать код.
Стандартное значение этой опции, как и прошлых двух, вызывает у меня недоумение.
Что ж, с настройкой и установкой Android Studio мы разобрались, пришло время создать наш первый проект.
В главном окне Android Studio нажмите на «Start a new Android Studio project «:
Появится новое окно, в котором нам нужно выполнить несколько действий.
В первом нужно задать имя приложения, домен компании (из этих двух параметров будет создано имя пакета), и расположение проекта на диске:
В Android, как и в Java, основным идентификатором приложения является имя пакета. Если вы ранее работали с Java, вы знаете, что это такое. Тем же, кто не знает, рекомендую гугл, или, например, вот .
Далее Android Studio спросит нас, какие и каких версий SDK мы хотим использовать. Пока что нам хватит «Phone and Tablet» SDK, версию API поставьте 16 вместо рекомендуемой 15-й, поскольку API 15 уже неактуально и совсем не распространено:
На следующем экране нас спросят, какие компоненты приложения мы хотим создать. Выберите «Empty Activity»:
На следующем шаге просто нажмите «Finish», ничего не меняя.
По завершению этого процесса вы увидите, наконец-то, свой первый проект:
Он уже вполне работоспособен, но чтобы его запустить, нам понадобится эмулятор Android.
Для создания эмулятора Android нам понадобится Android AVD Manager (AVD = Android Virtual Device). Не беспокойтесь, ставить больше ничего не потребуется. Просто нажмите на эту кнопочку:
Потом на эту кнопочку:
А потом просто несколько раз кликните «Next» и, наконец, «Finish»
Пришло время запустить наш первый проект, созданный в Android Studio !
Нажмите на вот эту кнопку (или Shift-F10):
После этого вы увидите диалог, в котором вам будет предложено выбрать девайс, на котором IDE должна запустить собранное приложение:
Поставьте выделенную стрелкой галочку и нажмите «ОК». Начнется сборка проекта, запуск эмулятора, установка приложения на эмулятор, и запуск приложения.
На это уйдет некоторое время (чем мощнее ваш компьютер — тем меньше времени понадобится), поскольку эмулятор — вещь достаточно медлительная, несмотря на колоссальные улучшения в последние пару лет.
И вот, по прошествии 1-10 минут (после запуска эмулятора проекты, конечно же, будут собираться и запускаться быстрее), вы, наконец, увидите свой Hello World на экране эмулятора!
На этом все, а в следующем уроке мы рассмотрим .
Новые уроки добавляются каждый день! Чтобы ничего не пропустить, подпишитесь на нашу
Переменную JAVA_HOME теперь, вроде бы, можно не устанавливать, так как в Android Studio мы будем в настройках прописывать путь к JDK. Но я ее установил. Для этого нужно:
Если у вас установлена переменная среды ANDROID_SDK_HOME и вы хотите, чтобы она указывала на старую установку, то, по идее, это не должно стать проблемой, так как при настройке Android Studio мы укажем ей путь к SDK. Проблемы могут возникнуть, если эту переменную использует какое-либо из приложений, входящих в состав Android SDK.
После установки запускаем Android Studio.
Видим вот такой диалог
Появляется вот такой диалог
Диалог выглядит так
Также обратите внимание на Help me choose, прикольная штука
Если нажать Help me choose
, то откроется вот такой интересный диалог
Он содержит информацию по охвату устройств при выборе той или иной версии API. Прямоугольники версий API кликабельны, справа будет выведен список доступного в них функционала. Например, для предлагаемого по умолчанию Ice Cream Sandwich"а:
На следующем экране нам предлагается выбрать Activity
Появляется следующий диалог
В итоге должен открыться проект
Снова запускаем Build->Make Project . На этот раз у меня все собралось. Надеюсь, у вас тоже.
Появится диалог настройки виртуального устройства
Устройство появилось в списке
Пара слов о вкладке Device Definitions
На ней заданы доступные устройства (те, которые потом отображаются в выпадающем списке Device
при создании нового виртуального устройства). Чтобы создать новое устройство, нужно нажать на кнопку Create Device...
и озаботиться заполнением следующего диалога:
В конце концов, появится окно выбора устройства
Здесь единственный доступный вариант для выбора - это наше виртуальное устройство. Он нам сразу предложен, так что просто жмем OK .
Запускается эмулятор, довольно долго
Android Device Monitor
Появился немного изменившийся диалог
Здесь устройство перекочевало из списка для запуска в список уже запущенных. В этом списке, само собой, оказываются и реальные устройства.
После этого дело пошло, и приложение довольно быстро установилось и запустилось.
Полноэкранный режим
А если на приложение тапнуть, то выглядит оно так
Это не поведение системы, обработка клика происходит в приложении (файл FullscreenActivity.java):
// Set up the user interaction to manually show or hide the system UI.
contentView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
if (TOGGLE_ON_CLICK) {
mSystemUiHider.toggle();
} else {
mSystemUiHider.show();
}
}
});
После запуска, Android Studio предложила мне выключить Android Device Monitor, для того чтобы интегрировать вывод прямо в IDE.
Вот как выглядит интеграция
Снова уже знакомый нам диалог
Ждем, пока запустится приложение и приконнектится дебаггер. Я поставил точку останова при нажатии на кнопку Dummy Button.
Android Studio в дебаге
Все это находится в меню Run
Необходимое отмечено галочками на скриншоте
Настройки нового устройства
В диалоге выбираем новое устройство для запуска
Запуск
Полноэкранный режим
После нажатия
Huawei Ascend G300 с Android 4.0.3
После того как драйвер был установлен, нужно на устройстве разрешить отладку по USB. У меня на телефоне для этого нужно зайти в Настройки->Для разработчиков->Отладка по USB . Но для разных устройств, а также сборок и версий Android, расположение этого пункта меню может отличаться.
Теперь телефон будет находиться Android SDK, а разрабатываемые приложения будут устанавливаться. Однако, для Huawei это еще не все: с телефона не идут логи, нужно их включить.
Как включить логи на Huawei
Набрать в качестве телефонного номера: *#*#2846579#*#*
Появится сервисное меню.
Перейти в ProjectMenu->Background Setting->Log Setting
Открыть Log switch
и установить там ON
.
Открыть Log level setting
и установить необходимый вам уровень логирования (я поставил verbose
).
Перезагрузить телефон.
В диалоге выбора устройства появилось реальное устройство
Результат запуска.
Приложение в портрете:
Приложение в ландшафте:
Альтернативно, вместо указания глобальной переменной можно прописать путь к ndk в файле local.properties
вашего проекта (прямо в корневой папке: MyApplication\local.properties
). Содержимое файла будет выглядеть примерно так (обратите внимание на двойные бэкслеши, так как для Windows это критично):
## This file is automatically generated by Android Studio.
# Do not modify this file -- YOUR CHANGES WILL BE ERASED!
#
# This file should *NOT* be checked into Version Control Systems,
# as it contains information specific to your local configuration.
#
# Location of the SDK. This is only used by Gradle.
# For customization when using a Version Control System, please read the
# header note.
sdk.dir=C:\\Users\\
Не верьте дисклеймеру про «ваши изменения будут выкинуты», в данном случае это не так. Обратите внимание, что этот файл рекомендуется исключать из-под контроля версий, так как он содержит только локальную для пользователя информацию. Для разнообразия в этом нам не соврали. Ну и, само собой, это изменение никак не повлияет на другие Ваши проекты. При установленной ANDROID_NDK_HOME
прописывать путь в local.properties необязательно.
Что надо скачать
Как запустить ndkSanAngeles
После того, как сэмплы скачаны, их нужно распаковать. Затем нужно открыть проект ndkSanAngeles. Для Android Studio проектом является папка, так что открывать надо именно ее. Для того этого выполняем File->Open
, либо, если вы в Welcome диалоге, Open Project
. Ищем папку ndkSanAngeles через диалог открытия файла.
После открытия проекта стоит обратить взор на файл build.gradle
. Вот его оригинал:
buildscript {
repositories {
mavenCentral()
}
dependencies {
classpath "com.android.tools.build:gradle:0.11.0"
}
}
apply plugin: "android"
android {
compileSdkVersion 19
buildToolsVersion "19.1.0"
defaultConfig {
ndk {
moduleName "sanangeles"
cFlags "-DANDROID_NDK -DDISABLE_IMPORTGL"
ldLibs "GLESv1_CM", "dl", "log"
stl "stlport_static"
}
// This actual the app version code. Giving ourselves 1,000,000 values
versionCode = 123
}
buildTypes.debug.jniDebugBuild true
productFlavors {
x86 {
ndk {
abiFilter "x86"
}
// this is the flavor part of the version code.
// It must be higher than the arm one for devices supporting
// both, as x86 is preferred.
versionCode = 3
}
arm {
ndk {
abiFilter "armeabi-v7a"
}
versionCode = 2
}
mips {
ndk {
abiFilter "mips"
}
versionCode = 1
}
fat {
// fat binary, lowest version code to be
// the last option
versionCode = 0
}
}
// make per-variant version code
applicationVariants.all { variant ->
А вот измененная версия, чтобы проект собирался у меня:
buildscript {
repositories {
mavenCentral()
}
dependencies {
classpath "com.android.tools.build:gradle:0.12.+"
}
}
apply plugin: "android"
android {
compileSdkVersion 19
buildToolsVersion "20.0.0"
defaultConfig {
ndk {
moduleName "sanangeles"
cFlags "-DANDROID_NDK -DDISABLE_IMPORTGL"
ldLibs "GLESv1_CM", "dl", "log"
stl "stlport_static"
}
// This actual the app version code. Giving ourselves 1,000,000 values
versionCode = 123
}
buildTypes.debug.jniDebugBuild true
productFlavors {
x86 {
ndk {
abiFilter "x86"
}
// this is the flavor part of the version code.
// It must be higher than the arm one for devices supporting
// both, as x86 is preferred.
versionCode = 3
}
arm {
ndk {
abiFilter "armeabi-v7a"
}
versionCode = 2
}
mips {
ndk {
abiFilter "mips"
}
versionCode = 1
}
fat {
// fat binary, lowest version code to be
// the last option
versionCode = 0
}
}
// make per-variant version code
applicationVariants.all { variant ->
// get the single flavor
def flavorVersion = variant.productFlavors.get(0).versionCode
// set the composite code
variant.mergedFlavor.versionCode = flavorVersion * 1000000 + defaultConfig.versionCode
}
}
Изменения следующие:
MyApplication->build.gradle
// Top-level build file where you can add configuration options common to all sub-projects/modules. buildscript { repositories { jcenter() } dependencies { classpath "com.android.tools.build:gradle:0.12.+" // NOTE: Do not place your application dependencies here; they belong // in the individual module build.gradle files } } allprojects { repositories { jcenter() } }
MyApplication->app->build.gradle
apply plugin: "com.android.application"
android {
compileSdkVersion 20
buildToolsVersion "20.0.0"
defaultConfig {
applicationId "com.example.markedone.myapp"
minSdkVersion 15
targetSdkVersion 20
versionCode 1
versionName "1.0"
}
buildTypes {
release {
runProguard false
proguardFiles getDefaultProguardFile("proguard-android.txt"), "proguard-rules.pro"
}
}
}
dependencies {
compile fileTree(dir: "libs", include: ["*.jar"])
// You must install or update the Support Repository through the SDK manager to use this dependency.
//compile "com.android.support:support-v4:19.+"
compile "com.android.support:support-v4:20.+"
}
Для начала, заменим
compileSdkVersion 20
на
compileSdkVersion 19
так как NDK ограничен версией 19.
В defaultConfig
мы добавим настройки ndk
, а также заменим targetSdkVersion
на 19:
defaultConfig {
applicationId "com.example.markedone.myapp"
minSdkVersion 15
targetSdkVersion 19
versionCode 1
versionName "1.0"
ndk {
moduleName "myapp"
cFlags "-DANDROID_NDK"
ldLibs "log"
stl "stlport_static"
}
}
Настройки NDK включают в себя
Полный листинг измененного файла build.gradle
apply plugin: "com.android.application" android { compileSdkVersion 19 buildToolsVersion "20.0.0" defaultConfig { applicationId "com.example.markedone.myapp" minSdkVersion 15 targetSdkVersion 19 versionCode 1 versionName "1.0" ndk { moduleName "myapp" cFlags "-DANDROID_NDK" ldLibs "log" stl "stlport_static" } } buildTypes { release { runProguard false proguardFiles getDefaultProguardFile("proguard-android.txt"), "proguard-rules.pro" } debug.jniDebugBuild true } productFlavors { x86 { ndk { abiFilter "x86" } // this is the flavor part of the version code. // It must be higher than the arm one for devices supporting // both, as x86 is preferred. versionCode = 3 } arm { ndk { abiFilter "armeabi-v7a" } versionCode = 2 } mips { ndk { abiFilter "mips" } versionCode = 1 } fat { // fat binary, lowest version code to be // the last option versionCode = 0 } } // make per-variant version code applicationVariants.all { variant -> // get the single flavor def flavorVersion = variant.productFlavors.get(0).versionCode // set the composite code variant.mergedFlavor.versionCode = flavorVersion * 1000000 + defaultConfig.versionCode } sourceSets { main { jni.srcDirs = ["src/main/jni", "src/main/jni/"] } } } dependencies { compile fileTree(dir: "libs", include: ["*.jar"]) // You must install or update the Support Repository through the SDK manager to use this dependency. compile "com.android.support:support-v4:19.+" }
New->Directory
New->Folder->JNI Folder
Он запускает визард создания папки
В первом диалоге мы выбираем, для какой части модуля будет создана папка jni, а во втором можно изменить ее расположение.
New->File
Описание
Описание
Содержимое файла
package com.example.markedone.myapp;
import com.example.markedone.myapp.util.SystemUiHider;
import android.annotation.TargetApi;
import android.app.Activity;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.view.MotionEvent;
import android.view.View;
/**
* An example full-screen activity that shows and hides the system UI (i.e.
* status bar and navigation/system bar) with user interaction.
*
* @see SystemUiHider
*/
public class FullscreenActivity extends Activity {
/**
* Whether or not the system UI should be auto-hidden after
* {@link #AUTO_HIDE_DELAY_MILLIS} milliseconds.
*/
private static final boolean AUTO_HIDE = true;
/**
* If {@link #AUTO_HIDE} is set, the number of milliseconds to wait after
* user interaction before hiding the system UI.
*/
private static final int AUTO_HIDE_DELAY_MILLIS = 3000;
/**
* If set, will toggle the system UI visibility upon interaction. Otherwise,
* will show the system UI visibility upon interaction.
*/
private static final boolean TOGGLE_ON_CLICK = true;
/**
* The flags to pass to {@link SystemUiHider#getInstance}.
*/
private static final int HIDER_FLAGS = SystemUiHider.FLAG_HIDE_NAVIGATION;
/**
* The instance of the {@link SystemUiHider} for this activity.
*/
private SystemUiHider mSystemUiHider;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_fullscreen);
final View controlsView = findViewById(R.id.fullscreen_content_controls);
final View contentView = findViewById(R.id.fullscreen_content);
// Set up an instance of SystemUiHider to control the system UI for
// this activity.
mSystemUiHider = SystemUiHider.getInstance(this, contentView, HIDER_FLAGS);
mSystemUiHider.setup();
mSystemUiHider
.setOnVisibilityChangeListener(new SystemUiHider.OnVisibilityChangeListener() {
// Cached values.
int mControlsHeight;
int mShortAnimTime;
@Override
@TargetApi(Build.VERSION_CODES.HONEYCOMB_MR2)
public void onVisibilityChange(boolean visible) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB_MR2) {
// If the ViewPropertyAnimator API is available
// (Honeycomb MR2 and later), use it to animate the
// in-layout UI controls at the bottom of the
// screen.
if (mControlsHeight == 0) {
mControlsHeight = controlsView.getHeight();
}
if (mShortAnimTime == 0) {
mShortAnimTime = getResources().getInteger(android.R.integer.config_shortAnimTime);
}
controlsView.animate()
.translationY(visible ? 0: mControlsHeight)
.setDuration(mShortAnimTime);
} else {
// If the ViewPropertyAnimator APIs aren"t
// available, simply show or hide the in-layout UI
// controls.
controlsView.setVisibility(visible ? View.VISIBLE: View.GONE);
}
if (visible && AUTO_HIDE) {
// Schedule a hide().
delayedHide(AUTO_HIDE_DELAY_MILLIS);
}
}
});
// Set up the user interaction to manually show or hide the system UI.
contentView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
if (TOGGLE_ON_CLICK) {
mSystemUiHider.toggle();
} else {
mSystemUiHider.show();
}
}
});
// Upon interacting with UI controls, delay any scheduled hide()
// operations to prevent the jarring behavior of controls going away
// while interacting with the UI.
findViewById(R.id.dummy_button).setOnTouchListener(mDelayHideTouchListener);
}
@Override
protected void onPostCreate(Bundle savedInstanceState) {
super.onPostCreate(savedInstanceState);
// Trigger the initial hide() shortly after the activity has been
// created, to briefly hint to the user that UI controls
// are available.
delayedHide(100);
}
/**
* Touch listener to use for in-layout UI controls to delay hiding the
* system UI. This is to prevent the jarring behavior of controls going away
* while interacting with activity UI.
*/
View.OnTouchListener mDelayHideTouchListener = new View.OnTouchListener() {
@Override
public boolean onTouch(View view, MotionEvent motionEvent) {
if (AUTO_HIDE) {
delayedHide(AUTO_HIDE_DELAY_MILLIS);
}
return false;
}
};
Handler mHideHandler = new Handler();
Runnable mHideRunnable = new Runnable() {
@Override
public void run() {
mSystemUiHider.hide();
}
};
/**
* Schedules a call to hide() in milliseconds, canceling any
* previously scheduled calls.
*/
private void delayedHide(int delayMillis) {
mHideHandler.removeCallbacks(mHideRunnable);
mHideHandler.postDelayed(mHideRunnable, delayMillis);
}
}
Теперь мы, в общем-то, уже можем вызвать нашу функцию. Если вы, как и я, выбрали FullscreenActivity, то у нас есть Dummy Button, который, по сути, ничего не делает. И даже уже есть touch listener, пусть и не самый лучший (он будет вызываться много раз, пока палец на экране), но, чтобы не плодить лишний код, используем его.
Для начала добавим в список импорта:
import android.widget.Button;
чтобы можно было нормально работать с кнопкой.
Найдем следующий код:
View.OnTouchListener mDelayHideTouchListener = new View.OnTouchListener() {
@Override
public boolean onTouch(View view, MotionEvent motionEvent) {
if (AUTO_HIDE) {
delayedHide(AUTO_HIDE_DELAY_MILLIS);
}
return false;
}
};
и добавим несколько строк перед return false .
View.OnTouchListener mDelayHideTouchListener = new View.OnTouchListener() {
@Override
public boolean onTouch(View view, MotionEvent motionEvent) {
if (AUTO_HIDE) {
delayedHide(AUTO_HIDE_DELAY_MILLIS);
}
final String message = stringFromJNI();
final Button button = (Button)findViewById(R.id.dummy_button);
final String actualText = button.getText().toString();
if(message.equals(actualText)) {
button.setText("Dummy Button");
}
else {
button.setText(message);
}
return false;
}
};
Описание добавленного кода
Полный листинг класса измененного класса
package com.example.markedone.myapp;
import com.example.markedone.myapp.util.SystemUiHider;
import android.annotation.TargetApi;
import android.app.Activity;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.view.MotionEvent;
import android.view.View;
import android.widget.Button;
/**
* An example full-screen activity that shows and hides the system UI (i.e.
* status bar and navigation/system bar) with user interaction.
*
* @see SystemUiHider
*/
public class FullscreenActivity extends Activity {
static {
System.loadLibrary("myapp");
}
private static native String stringFromJNI();
/**
* Whether or not the system UI should be auto-hidden after
* {@link #AUTO_HIDE_DELAY_MILLIS} milliseconds.
*/
private static final boolean AUTO_HIDE = true;
/**
* If {@link #AUTO_HIDE} is set, the number of milliseconds to wait after
* user interaction before hiding the system UI.
*/
private static final int AUTO_HIDE_DELAY_MILLIS = 3000;
/**
* If set, will toggle the system UI visibility upon interaction. Otherwise,
* will show the system UI visibility upon interaction.
*/
private static final boolean TOGGLE_ON_CLICK = true;
/**
* The flags to pass to {@link SystemUiHider#getInstance}.
*/
private static final int HIDER_FLAGS = SystemUiHider.FLAG_HIDE_NAVIGATION;
/**
* The instance of the {@link SystemUiHider} for this activity.
*/
private SystemUiHider mSystemUiHider;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_fullscreen);
final View controlsView = findViewById(R.id.fullscreen_content_controls);
final View contentView = findViewById(R.id.fullscreen_content);
// Set up an instance of SystemUiHider to control the system UI for
// this activity.
mSystemUiHider = SystemUiHider.getInstance(this, contentView, HIDER_FLAGS);
mSystemUiHider.setup();
mSystemUiHider
.setOnVisibilityChangeListener(new SystemUiHider.OnVisibilityChangeListener() {
// Cached values.
int mControlsHeight;
int mShortAnimTime;
@Override
@TargetApi(Build.VERSION_CODES.HONEYCOMB_MR2)
public void onVisibilityChange(boolean visible) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB_MR2) {
// If the ViewPropertyAnimator API is available
// (Honeycomb MR2 and later), use it to animate the
// in-layout UI controls at the bottom of the
// screen.
if (mControlsHeight == 0) {
mControlsHeight = controlsView.getHeight();
}
if (mShortAnimTime == 0) {
mShortAnimTime = getResources().getInteger(android.R.integer.config_shortAnimTime);
}
controlsView.animate()
.translationY(visible ? 0: mControlsHeight)
.setDuration(mShortAnimTime);
} else {
// If the ViewPropertyAnimator APIs aren"t
// available, simply show or hide the in-layout UI
// controls.
controlsView.setVisibility(visible ? View.VISIBLE: View.GONE);
}
if (visible && AUTO_HIDE) {
// Schedule a hide().
delayedHide(AUTO_HIDE_DELAY_MILLIS);
}
}
});
// Set up the user interaction to manually show or hide the system UI.
contentView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
if (TOGGLE_ON_CLICK) {
mSystemUiHider.toggle();
} else {
mSystemUiHider.show();
}
}
});
// Upon interacting with UI controls, delay any scheduled hide()
// operations to prevent the jarring behavior of controls going away
// while interacting with the UI.
findViewById(R.id.dummy_button).setOnTouchListener(mDelayHideTouchListener);
}
@Override
protected void onPostCreate(Bundle savedInstanceState) {
super.onPostCreate(savedInstanceState);
// Trigger the initial hide() shortly after the activity has been
// created, to briefly hint to the user that UI controls
// are available.
delayedHide(100);
}
/**
* Touch listener to use for in-layout UI controls to delay hiding the
* system UI. This is to prevent the jarring behavior of controls going away
* while interacting with activity UI.
*/
View.OnTouchListener mDelayHideTouchListener = new View.OnTouchListener() {
@Override
public boolean onTouch(View view, MotionEvent motionEvent) {
if (AUTO_HIDE) {
delayedHide(AUTO_HIDE_DELAY_MILLIS);
}
final String message = stringFromJNI();
final Button button = (Button)findViewById(R.id.dummy_button);
final String actualText = button.getText().toString();
if(message.equals(actualText)) {
button.setText("Dummy Button");
}
else {
button.setText(message);
}
return false;
}
};
Handler mHideHandler = new Handler();
Runnable mHideRunnable = new Runnable() {
@Override
public void run() {
mSystemUiHider.hide();
}
};
/**
* Schedules a call to hide() in milliseconds, canceling any
* previously scheduled calls.
*/
private void delayedHide(int delayMillis) {
mHideHandler.removeCallbacks(mHideRunnable);
mHideHandler.postDelayed(mHideRunnable, delayMillis);
}
}
Работа на реальном устройстве
Вывод сообщения в лог
Также, видно, что поддержка NDK еще сыровата, но прослеживается движение в этом направлении. Очень надеюсь, что они все-таки сделают полноценную поддержку C++-разработки.
P.S. Дебага C++ кода пока не обнаружено.
Теги:
Android - бесплатная операционная система, основанная на Linux с интерфейсом программирования Java.
Если у вас появилось желание разрабатывать приложения для телефонов под управлением Android, то вам необходимо тщательно подготовиться и установить весь необходимый инструментарий для работы.
Статьи часто перерабатываются, так как некоторые вещи быстро устаревают. Но уследить за всем я не могу, поэтому в чём-то придётся разбираться самостоятельно, если встретите различия.
Важно понимать, что само приложение пишется на Java (а теперь ещё и на Kotlin), а среда разработки выбирается по вкусу. То, что можно сделать на Android Studio (или в его старшем брате IntelliJ IDEA), можно сделать и на Eclipse и в других редакторах. Хотя с 2016 официальная поддержка Eclipse прекратилась.
Скачать установочный пакет для студии можно со страницы https://developer.android.com/studio/index.html
Сама установка проблем вызвать не должна. Установочный пакет включает в себя необходимый минимум. Иногда вам необходимо запускать Android SDK Manager и проверять наличие новых версий SDK через меню Tools | Android | SDK Manager :
Со временем вы сами разберётесь, что вам нужно ставить, а что не обязательно. На первых порах соглашайтесь на те условия, которые вам предложит менеджер по умолчанию.
Пользователь из Болгарии написал, что в Win64 требуются права администратора при установке или обновлении. Имейте в виду. У меня на чистой системе ничего не спрашивало.
В версии студии 2.3 (может и раньше) ставится пакет OpenJDK, который является альтернативой JDK от Oracle. В настройках студии есть примечание, что OpenJDK является рекомендуемым вариантом, хотя вы можете указать путь и к стандартной JDK. В любом случае у вас будет Java 8 вне зависимости, какой вариант вы выберете.
Для отладки приложений используется эмулятор телефона - виртуальная машина, на которой будет запускаться наше приложение. Также можно использовать и реальное устройство.
Сейчас в момент установки студия создаёт одно устройство для эмулятора. Если это не так, вы всегда можете установить вручную. А также можете добавить и другие устройства под разные версии Android, разрешения экрана и т.д.
Чтобы создать эмулятор телефона, выбираем в меню Tools | Android | AVD Manager . При первом запуске появится диалоговое окно мастера.
Нажимаем кнопку Create a virtual device и в новом окне видим набор возможных эмуляторов, в том числе и для часов. Скачайте необходимые эмуляторы. Для начала вполне подойдёт один эмулятор.
Вводим любое понятное имя, например, Android4. Выбираем нужную версию Android, размер экрана и т.д.
При необходимости можно создать эмуляторы для каждой версии ОС и проверять программу на работоспособность. Остальные настройки можно оставить без изменений. Вы всегда можете вернуться к настройкам и отредактировать снова. Часто рекомендуют использовать опцию Use Host GPU , чтобы задействовать возможности графического процессора. Это даёт прирост скорости эмулятора. Нажимаем кнопку OK .
Добавленные эмуляторы будут храниться в менеджере эмуляторов.
Если вы создали несколько эмуляторов, то выделите нужный и нажмите кнопку с зелёным треугольником для запуска эмулятора. Значок карандаша позволяет отредактировать настройки. Но обычно эмулятор не запускают отдельно. Когда вы будете запускать приложение, то студия сама предложит запустить эмулятор.
Помните, что виртуальные машины по умолчанию сохраняются в папке пользователя, и пути к папке не должны содержать русские символы во избежание проблем.
Если вы всё же попались в эту ловушку, то дам ссылку по смене папки пользователя на английский: http://www.cherneenet.ru/lokalnaj_zapis.html (спасибо читателю Евгению Степанову за подсказку). Также можно подправить ini-файл и прописать путь к виртуальному устройству таким образом, чтобы в пути не встречались русские буквы (соответственно, сам файл *.avd также нужно переместить в другое место).
В зависимости от мощности компьютера нужно немного подождать, чтобы сначала загрузился эмулятор. Эмулятор от Intel загружается на порядок быстрее. Также можно использовать реальный телефон. Я обычно использую старый телефон и эмулятор для новых версий Android.
Окончательную версию приложения желательно проверять на настоящем устройстве. Начиная с Android 4.4, на устройстве (планшет, телефон, часы) нужно активировать режим разработчика. Для этого идём в Настройки, там открываем страницу "О телефоне" и щёлкаем семь раз на строчке с номером сборки Build number . После этого в настройках появится новый пункт Для разработчиков или что-то в этом роде, если производитель использует свою оболочку.
Открыв страницу для разработчиков, вам нужно включить отладку через USB. Также я включаю опцию Не выключать экран . Для некоторых устройств требуется установить отдельный драйвер, ищите информацию на сайте у производителей.
Студия также позволяет запускать команды командной строки в отдельном окне . Для удобства следует немного настроить систему под себя.
У меня установлена нелокализованая версия Windows, поэтому часть пунктов будут даны на английском.
Для Windows 7/8 откройте Панель управления | Система , нажмите кнопку Advanced System Settings . В новом окне нажмите кнопку Environment Variables .
Найдите переменную Path в списке System variables
Нажмите на кнопку Edit для редактирования переменной. Добавьте в конце строки точку с запятой, а затем укажите пути к папкам platform-tools и tools , которые входят в состав SDK. В моём случае получилось следующее:
;D:\Android\SDK\platform-tools;D:\Android\SDK\tools
Закройте все окна (лучше перезагрузиться). Проверьте, правильно ли всё работает. Запустите командную строку и введите команду:
Echo %path%
Вы должны увидеть строку с перечислением всех путей, входящих в переменную Path , в том числе и ваши.
Для следующей проверки введите команду:
Запустится перечень параметров команды.
Также попробуйте команду:
Запустится окно SDK Manager.
Если вы что-то прописали не так, то команды не будут распознаны и вам надо исправить ошибку в написании пути.
Теперь проделаем эти операции в самой студии. Запустите студию и откройте проект (см. следующий урок). Внизу в строке состояния есть вкладка . Переключитесь на неё. В окне терминала введите любую из двух предыдущих команд.
Последнюю версию документации всегда можно найти по адресу developer.android.com . Если у вас возникли проблемы с интернетом, то в подпапке /docs в вашей папке установленной Android SDK можно найти ее локальную копию (если вы не отказывались от её установки).
Данный пункт не является обязательным, но как показывает практика, наличие кота позволяет добиться быстрых результатов в изучении Android. Кота можно подобрать на улице, взять из приюта, купить по объявлению. Подойдут всякие - рыжие, полосатые, чёрные. Кота следует помыть, накормить и посадить рядом. Ваша карма в это время растёт и процесс освоения материала пойдёт быстрее.
Подготовка к разработке завершена. Теперь следующий этап - создание первого приложения .
Устраивайтесь поудобнее в кресле и пристегните ремни - нас ждёт увлекательное путешествие в мир разработки приложений под Android.
Так как мы пишем под Android, то и для запуска приложений нам понадобиться смартфон под его управлением, но, конечно же, есть эмулятор и вы уже даже скачали его вместе с Android Studio. Правда, работает он не сразу из коробки и придётся немного настроить его. В этой статье мы это и сделаем.
Виртуальные Android-девайсы необходимы для тестирования приложений без установки их на реальные устройства, для сокращения их называют AVD (от английского Android Virtual Device). Они могут быть сконфигурированы для эмуляции различных аппаратных характеристик таких как разные размеры экрана, объемы памяти, наличие или отсутствие камер, поддержка GPS навигации или акселерометра. При стандартной установке Android Studio устанавливается набор шаблонов устройств по умолчанию, в основном, это телефоны Nexus, позволяющие на их основе создавать свои AVD. Можно также скачивать дополнительные шаблоны или создавать свои, чтобы они соответствовали каким-либо Android-девайсам по типу процессора, объему памяти, плотности пикселей и размеру экрана.
При запуске AVD выглядит как окно, эмулирующее устройство. Для примера фото ниже.
Новые AVD создаются и управляются в Android Virtual Device Manager, с которым можно работать как в командной строчке, так и в удобном графическом интерфейсе. Запустить менеджер можно из Android Studio выбрав опцию меню Tools -> Android -> AVD Manager. В рамках данной статьи мы не будем рассматривать работу через командную строчку.
Запустив AVD Manager, нажмите кнопку "Create a virtual device", появится окно конфигурации виртуального устройства.
Для примера создадим эмулятор Nexus S. Мы выбираем его, потому что у него довольно маленький экран, а значит при запуске виртуального девайса процессор будет менее загружен. Нам совсем не нужен большой экран для Hello World, впоследствии вы, конечно, можете создать себе свой экземпляр и работать с более приближенными к реальности конфигурациями.
Как видите есть несколько вкладок для различных категорий устройств, нам нужна вторая под именем Phone. На ней выбираем первую же строчку, Nexus S, нажимаем Next и ждём окончания установки. После этого появится окно настроек:
Здесь можно задать название и разнообразные настройки. Давайте, ничего не будем трогать и просто нажмём Finish. На этом создание нового AVD закончено.
Чтобы запустить эмулятор просто нажмите на зелёный треугольник напротив его названия на главной странице AVD Manager. Запуск, особенно первый, занимает довольно много времени. Для ускорения последующих запусков уберите галочку "Use Host GPU" и поставьте напротив "Store a snapshot for faster startup".
Snapshot это что-то вроде снимка состояния эмулятора, который загружается при запуске виртуального устройства и позволяет сократить время запуска до нескольких секунд. Включить эту функцию можно только при отключении опции "Use Host GPU".
Также для ускорения разработки можно не выключать эмулятор при работе в Android Studio, чтобы при каждом запуске приложения не было бы необходимости ожидать его запуска, студия поймёт, что запускать необходимо уже в работающем эмуляторе.
Теперь у нас есть всё необходимое для написания первого приложения под Android. В следующей статье мы уже запустим его.