Android — Android SDK. Вызов View из другого класса


Содержание
Цукерберг рекомендует:  Html - Не отображает картинку. Я прописывал bg-image - не работает

Android Study

СОЗДАНИЕ ПРИЛОЖЕНИЙ

Урок 12. Из одного Activity в другое

Урок 12. Из одного Activity в другое

На данный момент если вы запустите наше приложение у вас не будет возможности попасть на экран, который выводит вопрос и предлагает три варианта ответа (activity_game.xml). Нам необходимо сделать так, чтобы по нажатии кнопки «Play» на экране activity_main.xml мы попадали на экран с игрой activity_game.xml. Открывайте проект с нашей математической игрой и следуйте по пунктам:

  • Открываем файл acitivity_main.xml (либо двойным щелчком в проводнике проекта, либо щелчком на вкладку в случае, когда она не активна);
  • Теперь, как мы уже делали это раньше (с текстовыми элементами) нам нужно назначить id кнопке Play. Кликните по кнопке Play или найдите её в «Componenttree» и в свойствах кнопки найдите ID и назначьте там «buttonPlay»;
  • Теперь перейдите в MainActivity.java.
  • В теле метода onCreate, сразу же после строки с методом setContentView добавьте выделенную строку:
  • Позже мы подробнее проанализируем весь код целиком, а пока нужно знать, что мы этой строкой кода создаём ссылочную переменную (объект) и присоединяем к кнопке Play. Так же как мы делали раньше, после добавления этой строки необходимо будет импортировать класс Button в наш проект комбинацией клавиш Alt+Enter.
  • Теперь кое-что новенькое. Мы дадим кнопке способность «слушать» клик пользователя. Сразу же после предыдущего кода напишите это:

Заметьте, что ключевое слово this подчеркнуто красным цветом, что указывает нам на ошибку. В дальнейших уроках будет подробное объяснение почему так происходит. Оставим это пока в уме. Нам нужно внести изменения в наш код и разрешить использование интерфейса (очень мощный инструмент в программировании, о нём тоже попозже, дабы не захламлять голову большим количеством теории без практического применения), позволяющего нам добавлять функциональные возможности, такие как «прослушивание» щелчков по кнопкам. Отредактируйте эту строку:

Теперь вся эта строка подчеркнута красным. Добавив implements View.onClickListener мы реализовали интерфейс. Интерфейс – это как класс, но со своими правилами. Правило интерфейса onClickListener гласит, что мы обязаны реализовать/использовать один из его методов. Давайте сделаем это.

  • Обратите внимание на открывающую фигурную скобку (<) и закрывающую (>). Они обозначают начало и конец метода. Наш метод пуст, и он ничего не делает, но этого вполне достаточно для соответствия правилу интерфейса onClickListener. Красная строка уйдёт. Убедитесь, что вы ввели следующий код после закрывающей фигурной скобки метода onCreate, но перед закрывающей фигурной скобкой нашего класса MainActivity:

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

Добавленный код выделен жирным. Не забудьте импортировать класс Intent.

  • Пока этот код для нас немного непонятен. Отгадка кроется в методе startActivity и знакомом нам термине GameActivity. Обратите внимание, что мы присваиваем что-то переменной «i». Понимание всего происходящего придёт после уроков, где мы будем разбирать понятие Объектно-Ориентированного Программирования. А сейчас давайте запустим наше приложение. Если всё сделано правильно, то вы перед собой должны увидеть это:
Цукерберг рекомендует:  Красивое портфолио с помощью jQuery

При нажатии кнопки Play на экране меню (activity_main) вы перейдёте на экран с игровым процессом (activity_game). Если этого не произошло, внимательно прочтите статью еще раз и попробуйте найти какое-либо несоответствие. Последовательность строчек в коде очень важна, также как и расстановка фигурных скобок «<>». Всё должно соответствовать нашему описанию. Но если проблема не будет найдена вами, вы можете связаться со мной посредством комментария и подробно объяснить возникшее перед вами затруднение. Я попробую вам помочь.

Разбираемся в коде

Файл MainActivity.java – весь код целиком:

Разберём по кусочкам:

В первом куске мы видим определение имени нашего пакета и импортируем нужные нам библиотеки из Android API для взаимодействия в коде. Далее:

Тут происходит объявление нашего класса MainActivity с реализацией интерфейса View.OnClickListener, который даёт нам возможность засечь нажатие по кнопке. Далее:

Сперва строкой super.onCreate(savedInstanceState); мы просим выполнить некоторые вещи, которые скрыты в коде метода onCreate. По сути этой строкой мы задаём начальные настройки Activity. Строкой setContentView(R.layout.activity_main); устанавливаем созданный нами пользовательский интерфейс в файле activity_main.xml.

Далее мы создаём ссылку на нашу кнопку с ID buttonPlay:

И придаём ей возможность «слушать» нажатие по ней:

В конце, в методе onClick мы с помощью класса Intent отправляем пользователя в класс GameActivity, который в своём коде устанавливает в качестве экрана пользовательский интерфейс, созданный нами в файле activity_game.xml:

Теперь, когда мы немного изучили азы обработки событий, нам нужно изучить больше язык Java. Переходите к следующему уроку – в нём мы рассмотрим еще несколько операторов (помимо тех, что мы уже знаем), используя которые мы научим наше приложение не только задавать вопрос пользователю, но и реагировать на ответ.

andro >

Продолжение прошлого вопроса.

Есть 2 класса. Нужно в во 2 классе,выполнить метод из 1. Сам метод:

Как я его вызываю:

Приложение выкидывает ошибку.

Классы выглядят так (весь код класса кидать не буду,слишком много его):

    3 1


  • 3 янв 2012 2012-01-03 11:07:02
  • romanzi

1 ответ

Не претендую на правильность, но попробую изложить свои мысли

Скорее всего ничего не инициализировано в классе Client (конструктор пустой, не так ли?)

Подозреваю вся логика инициализации лежит в OnCreate() и все элементы управления у вас nullы

А вообще по-моему какой-то странный архитектурный подход

PS скорее всего Activity должна быть связана с контекстом

ПРОграммирование под Android

Страницы

28 ноября 2014 г.

Layouts (компоновки). Теория

Переходим к изучению Layouts. Или как часто переводят разметка, компоновка или представление элементов пользовательского интерфейса.

Все элементы пользовательского интерфейса в приложениях Андроид создаются с использованием объектов View и ViewGroup.

Класс View является базовым классом для ViewGroup и состоит из коллекции объектов View. Есть множество типов представлений и групп представлений, каждый из которых является потомком класса View.

На платформе Android необходимо определить пользовательский интерфейс для каждой Активности, используя иерархии узлов View и viewGroup. Это дерево иерархии может быть и простым, и сложным — в зависимости от требований к графическому интерфейсу приложения.

При запуске Активности система должна получить ссылку на корневой узел дерева разметки, который будет использоваться для прорисовки графического интерфейса на экране мобильного устройства. Для этого в методе onCreate() необходимо вызвать метод setСontentView(), передав ему в качестве параметра ссылку на ресурс разметки в следующем виде:

R.layout.layout_file_name

Например, если ваша XMLразметка сохранена как main.xml, вы загружаете разметку для Activity примерно так:

Прорисовка начинается с корневого узла дерева разметки. Затем последовательно прорисовываются дочерние представления дерева разметки. Это означает, что родители будут прорисовываться раньше, чем их дочерние представления, — т. е. по окончании процесса прорисовки родители будут находиться на заднем плане по отношению к дочерним узлам.

Разметка, как было сказано, — это архитектура расположения элементов интерфейса пользователя для конкретного окна, представляющего Активность. Она определяет структуру расположения элементов в окне и содержит все элементы, которые предоставляются пользователю программы. Разметку можно объявлять двумя способами:

  • объявить элементы пользовательского интерфейса в XML. Android обеспечивает прямой XMLсловарь, который соответствует классам View и ViewGroup;
  • создать разметку для окна в коде программы во время выполнения — инициализировать объекты Layout и дочерние объекты View, ViewGroup и управлять их свойствами программно.

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

ADT-плагин для Eclipse предлагает удобный инструментарий — визуальный редактор разметки Layout Editor, который применяется для создания и предварительного просмотра создаваемых файлов разметки, которые находятся в каталоге res/layout/ проекта.

Самый общий способ определять разметку и создавать иерархию представления— в XML файле разметки. XML предлагает удобную структуру для разметки, похожую на HTML разметку WEB страницы.

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

Например, вы можете создавать XML разметки для различных ориентаций экрана мобильного устройства (portrait, landscape), размеров экрана и языков интерфейса. Дополнительно, объявление разметки в XML файле облегчает возможность по визуализации структуры вашего пользовательского интерфейса, что упрощает отладку приложения.

Каждый элемент в XML является объектом View или ViewGroup (или его потомком). Объекты view— листья в дереве, объекты ViewGroup— ветви. Вы можете также создавать объекты View и viewGroups в Java-коде, используя метод addview (View), чтобы динамически вставлять новые объекты view и ViewGroup в существующую разметку.

Используя различные виды групп представлений, можно структурировать дочерние представления и группы представлений многими способами в зависимости от требований к графическому интерфейсу приложения. Некоторые стандартные группы представлений, предлагаемые Android (называющиеся разметками), включают LinearLayout, RelativeLayout, TableLayout и др. (будут подробно описаны позднее). Каждый из этих типов разметки предлагает уникальный набор параметров, которые используются, чтобы определить позиции дочерних представлений и структуру разметки на экране.
Объявление в XML

Используя XML словарь Android, можно быстро проектировать пользовательский интерфейс разметки и экранные элементы, которые он содержит, тем же самым способом, которым вы создаете web страницы в HTML — с рядом вложенных элементов.

Каждый файл разметки должен содержать только один корневой элемент, который должен быть объектом View или ViewGroup. Как только вы определили корневой элемент, вы можете добавить дополнительные объекты разметки или виджеты как дочерние элементы, чтобы постепенно формировать иерархию элементов, которую определяет создаваемая разметка.

Самый простой способ объяснять эту концепцию состоит в том, чтобы показать образец.

Общая структура XML файла разметки проста: это — дерево XML элементов, где каждый узел представляет имя класса View (в нашем примере только один элемент View— TextView). Вы можете использовать имя любого класса, производного от класса View, как элемент в XML разметках, включая ваши собственные классы. Эта структура позволяет быстро создавать пользовательский интерфейс, используя более простую структуру и синтаксис, чем при создании разметки в программном коде.

В вышеупомянутом XML примере есть корневой элемент и только один дочерний элемент View. TextView (текстовое поле), который имеет атрибуты. Описание некоторых из этих атрибутов приведем ниже:

  • xmlns:android – декларация пространства имен XML, которая сообщает среде Android, что вы ссылаетесь на общие атрибуты, определенные в пространстве имен Android. В каждом файле разметки у корневого элемента должен быть этот атрибут со значением «http://schemas.android.com/apk/res/android»
  • android:layout_width – этот атрибут определяет, сколько из доступной ширины на экране должен использовать этот объект View (или View Group). В нашем случае он — единственный объект, таким образом, можно растянуть его на весь экран, которому в данном случае соответствует значение mutch_parent
  • android:layout_height – аналогично android:layout_width, за исключением того, что он ссылается на доступную высоту экрана
  • android:text – устанавливает текст, который должен отобразить Textview. В этом примере используется строковый ресурс вместо жестко закодированного строкового значения. Строка hello определена в файле res/values/strings.xml. Это рекомендуемая практика для использования строковых ресурсов в ваших приложениях, потому что она делает локализацию приложения на другие языки более простой, без потребности кодировать напрямую изменения в файле разметки

Каждый объект View и ViewGroup поддерживает свое собственное разнообразие XML атрибутов. Некоторые атрибуты являются определенными только в объекте View (например, Textview поддерживает атрибут textSize), но эти атрибуты могут также наследоваться любыми объектами View, которые расширяют этот класс. Некоторые атрибуты являются общими ко всем объектам View, потому что они унаследованы от корневого класса View (подобно атрибутам id, layout_width, layout_height).

В общем, XML словарь элементов пользовательского интерфейса близок к структуре классов и методов этих элементов, где имя элемента соответствует имени класса, а атрибуты элемента — методам этого класса. Фактически, соответствие является часто настолько точным, что легко предположить без обращения к документации Android, какой XML атрибут передает метод класса или, наоборот, какой метод класса соответствует конкретному XML элементу.

Соответствие XML атрибутов и методов в классах представлений

android:gravity setGravity(int) android: height setHeight(int) android:text setText(CharSequence) android:textColor setTextColor(ColorStateList) android:textSize setrextSize (float) android:width setWidth(int) android:textColorHighlight setHighlightColor(int)

Любой объект View в коде программы можно связать с объектом из файла разметки, однозначно определив элемент пользовательского интерфейса в пределах дерева. Когда приложение откомпилировано, на этот идентификатор ссылаются как на целое число, но идентификатор представления обычно обозначается в XML файле разметки как строка в атрибуте id. Синтаксис для идентификатора элемента в XMLтеге следующий:


Символ @ в начале строки указывает, что синтаксический анализатор XML должен проанализировать и развернуть остальную часть строки идентификатора и определить это выражение как ресурс идентификатора. Символ + означает, что это — новое имя ресурса, которое должно быть создано и добавлено к нашим ресурсам в файл R.java, который среда Android автоматически генерирует для проекта, как показано в листинге.

Если в программном коде мы не работаем с некоторыми элементами пользовательского интерфейса, создавать идентификаторы для них необязательно, однако определение идентификаторов для объектов представления важно при создании RelativeLayout (относительной разметки). В RelativeLayout расположение представлений может определяться относительно другого представления, на которое ссылаются через его уникальный идентификатор:

andro

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

Существуют следующие стандартные типы разметок, которые вы можете использовать в создаваемых приложениях:

  • FrameLayout;
  • LinearLayout;
  • TableLayout;
  • RelativeLayout;
  • GridLayout.

Подобно всем разметкам, все они являются подклассами viewGroup и наследуют свойства, определенные в классе View.

Что самое интересное весь этот материал взят от сюда, ну кроме второго абзаца с верху который я сам перевел с альма-матер. Кто у кого стянул текст не понятно. То ли Голощапов, то ли этот сайт. Но на сайте инфы больше.

Расширенная SDK для Android SDK: настройка камеры и датчика

Russian (Pусский) translation by Dima (you can also view the original English article)

Сегодня расширенная реальность (AR) является горячей темой в мобильных приложениях. Смартфоны и планшеты имеют мощь и аппаратное обеспечение, которое позволяет разработчикам создавать интересные интересные приложения, которые интересны для использования живых камер и видеопотоков, гиперточных данных датчиков и других пользовательских данных в реальном времени. Сегодня мы начнем изучать мир дополненной реальности и то, что платформа Android может предложить разработчикам, которые хотят создавать AR-приложения и предоставлять своим пользователям глубокий и богатый опыт.

Также доступны в этой серии:

  1. Расширенная SDK для Android SDK: настройка камеры и датчика
  2. Android SDK Augmented Reality: Местоположение и расстояние

Шаг 0 : предварительные условия и начало работы

Этот урок движется довольно быстро. Таким образом, мы ожидаем, что читатели будут знать все основы создания и запуска проектов Android. Мы также ожидаем, что у читателей появится Android-устройство, достаточно мощное для запуска приложений AR (таких как Nexus S). Большинство тестов этого приложения необходимо будет сделать на реальном устройстве Android, так как приложение в значительной степени зависит от камеры, датчиков и данных местоположения, которые недоступны в эмуляторе.

Мы предоставили пример приложения в сочетании с этим учебным пособием для загрузки. Этот проект будет усилен в ходе серии премиальных AR-обучающих программ, поэтому загрузите проект Android и следуйте за ним!

Часть 1 : Какое AR-приложение мы разрабатываем?

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

Итак, какое приложение мы будем строить? Мы собираемся создать AR-приложение на основе местоположения. Эти типы приложений AR обычно показывают, где вещи находятся в реальном мире, указывая, где приложение считает, что они находятся над просмотром камеры, когда пользователь держит телефон и перемещает его.

Другим типом приложения AR является тип, который распознает объект, используя алгоритмы компьютерного зрения, и может либо нарисовать информацию по камере, чтобы показать, что такое объект, как он ориентирован, либо, возможно, добавить или показать другие объекты в представлении. Хотя мы не будем создавать такое AR-приложение, многие из методов, которые мы преподаем здесь, могут применяться к любому типу приложения AR.

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

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

Требования к приложениям : какие функции устройства Требуется ли наше приложение?

Для вашего типичного приложения AR требуется доступ к следующим функциям устройства:

  • Доступ к просмотру камеры
  • Доступ к местоположению пользователя
  • Доступ к другим датчикам устройства, особенно компас (акселерометр и гироскоп также могут быть полезны)

Приложению также могут потребоваться другие службы и разрешения, такие как доступ к сети, но они не являются центральными для AR-аспектов приложения.

Примечание по целевым устройствам : Nexus S

Не все устройства Android (или мобильные устройства в целом) имеют аппаратные спецификации для обработки требований AR-приложений. Для целей данного руководства мы ориентируемся на Nexus S, работающий под управлением Android 2.3.4, который удовлетворяет нашим специфическим требованиям к оборудованию. Поэтому наше приложение будет нацелено на очень специфическую версию Android SDK. Это упростит приложение. Однако требования SDK могут быть более гибкими, если манифест Android правильно идентифицирует любые требуемые аппаратные функции или вы реализуете альтернативные функции для менее мощных устройств.

Хотя Nexus S более чем способен выполнять разумные задачи AR, многие другие устройства также способны, включая некоторые более старые устройства. Если вы создаете производственное приложение, использующее технологию AR, вы должны тщательно протестировать на своих целевых устройствах ответ, удобство и правильную функциональность.

Часть 2 : Настройка проекта

Теперь мы готовы начать разработку! Сначала создадим проект AR. Это приложение настроено так же, как и любой другой проект приложения в Eclipse.

Шаг 1: Создайте новый проект Eclipse

Начните с создания нового проекта Android в Eclipse. Вот подробности проекта, которые мы использовали для образца проекта (доступны для загрузки):

  • Название проекта: ARTUT
  • Уровень API мин/цель: 10
  • Запуск действия класса: ArtutActivity

Шаг 2: Настройка файла манифеста


Затем вы хотите настроить файл манифеста Android. Вы должны указать следующие настройки:

На вкладке Манифест добавьте настройки для следующего:

    andro >На вкладке Приложение:

  • Отладка должна быть установлена ​​в true

На вкладке разрешения добавить настройки для:

Шаг 3: Подключите целевое устройство

Наконец, если вы еще этого не сделали, вам нужно настроить Android-устройство для тестирования и подключить его к компьютеру разработки через USB. Если вы этого еще не сделали, вам может потребоваться загрузить и установить драйверы перед использованием.

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

Часть 2: Работа с камерой

Наш первый реальный шаг в разработке AR-приложения включает в себя получение содержимого камеры, отображаемого на экране. Мы делаем это, реализуя пользовательский SurfaceView, который отображается в макете действия.

Шаг 1: Определение макета экрана App

Во-первых, нам нужно определить ресурс макета, который будет использоваться для основного экрана AR. FrameLayout наиболее подходит для нашего экрана, так как позволяет расслоение видов в области отображения. Поэтому наш ресурс компоновки, /res/layout/main.xml, может быть довольно простым:

Шаг 2: Определение пользовательского SurfaceView для хранения содержимого камеры.

Затем вам нужно определить пользовательский элемент управления представлением для использования в вашем FrameLayout. Для этой цели можно использовать класс SurfaceView. Поэтому вы можете использовать этот класс для инкапсуляции рисунка вашей камеры.

ArDisplayView класса начинается с конструктором. Мы добавили Activity как параметр конфигурации (подробнее об этом на следующем шаге). Конструктор должен инициализировать основной SurfaceHolder, который управляет рисунком на экране.

(Обратите внимание, что хотя метод setType () устарел, и в документации Android SDK говорится, что он больше не нужен, мы обнаружили, что код камеры не будет функционировать без него, он просто не запускается, даже на самом новом устройства.)

Мы добавили соответствующие переменные-члены для работы с камерой, и мы также поддерживаем активность, чтобы мы могли реагировать на изменения ориентации и любой другой удобный доступ к Контексту или Деятельности, которые могут нам понадобиться.

Шаг 3: Реализация обратных вызовов SurfaceHolder

Затем вам нужно будет реализовать обратные вызовы SurfaceHolder внутри класса. Обновите класс ArDisplayView, чтобы он реализовал интерфейс SurfaceHolder.Callback, например:

Это потребует переопределения и реализации трех новых методов: surfaceCreated (), surfaceChanged () и surfaceDestroyed ().

При работе с камерой предусмотрен ряд шагов, необходимых для запуска и выключения. Эти шаги четко описаны в документах Android SDK для класса Camera. Мы в основном отбрасываем эти шаги в соответствующие обратные вызовы SurfaceHolder.

Шаг 4: Реализация обратного вызова surfaceCreated ()

Начнем с метода обратного вызова surfaceCreated(). Здесь мы запрашиваем камеру, устанавливаем ориентацию дисплея камеры на основе текущей ориентации устройства (чтобы предварительный просмотр камеры всегда отображался справа вверх) и вызывал метод setPreviewDisplay (), чтобы связать предварительный просмотр камеры с нашим SurfaceHolder.

Шаг 5: Внедрение обратного вызова surfaceChanged()

Большая часть интересного кода для предварительного просмотра камеры происходит в обратном вызове surfaceChanged (). Здесь мы запрашиваем параметры камеры и проверяем, какие поддерживаемые размеры предварительного просмотра. Нам нужно найти размер предварительного просмотра, который может быть размещен на поверхности, поэтому мы ищем ближайшее совпадение и используем его как наш размер предварительного просмотра. Затем мы устанавливаем формат предварительного просмотра камеры, фиксируем изменения параметров камеры и, наконец, вызываем метод startPreview (), чтобы начать отображение предварительного просмотра камеры на нашей поверхности.

Шаг 6: Внедрение обратного вызова surfaceDestroyed ()

Мы заканчиваем методом обратного вызова surfaceDestroyed(). Здесь мы закрываем предварительный просмотр камеры и освобождаем ресурсы камеры.

Шаг 7: Пользовательский просмотр камеры и основная активность

Теперь вам нужно добавить свои пользовательские представления в элемент управления FrameLayout. Для этого обновите метод onCreate() класса ArtutActivity, например:

Это добавляет класс просмотра предварительного просмотра камеры, называемый ArDisplayView в FrameLayout. Если вы запустите приложение сейчас, действие запустится, и вы увидите предварительный просмотр камеры на экране.

Заметка о цифрах: Захват экрана DDMS по умолчанию не фиксирует предварительный просмотр камеры. Запустите приложение самостоятельно, чтобы увидеть настоящую функциональность.

Часть 3: Работа с датчиками устройства

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

Шаг 1: Отображение содержимого Overlay

Во-первых, вам нужно определить настраиваемый элемент управления представлением для наложения содержимого наложения. Создайте новый класс OverlayView, который является производным от класса View. Этот класс начинается просто для этой части учебника. Мы просто хотим наложить некоторые данные датчиков сверху камеры (пока еще нет фантазии). Для этого мы создаем переменные-члены для хранения последних известных данных датчика для каждого интересующего нас датчика. Затем мы реализуем метод onDraw () нашего представления и наносим некоторый текст на холст.

Метод onDraw() выполняет всю работу здесь. Мы настраиваем Paint с соответствующими текстовыми атрибутами, а затем рисуем текст на холсте с помощью метода drawText().

Зачем использовать пользовательский вид вместо обычных элементов управления? В дальнейшем нам понадобится точность для размещения объектов AR в пределах камеры, которые являются репрезентативными для местоположений мест реального мира. Альтернативой этому методу является использование 3D-рендеринга для лучшего получения дескриптора глубины и расстояния. В AR-приложении местоположения это обычно менее важно, поскольку расстояния часто довольно обширны (километров, а не метров).

Шаг 2: Реализация обратных вызовов SurfaceHolder


Затем вам необходимо реализовать интерфейс SensorEventListener в классе. Обновите класс OverlayView, чтобы он реализовал интерфейс SensorEventListener, например:

Это потребует переопределения и реализации двух новых методов: onAccuracyChanged() и onSensorChanged(). Для целей этого урока нас действительно интересует только метод onSensorChanged().

Шаг 3: Регистрация для обновлений данных датчиков

Прежде чем внедрять обратные вызовы SensorEventListener, мы хотим зарегистрироваться для соответствующих обновлений данных датчиков. Для этого обновите метод onCreate () класса OverlayView.

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

Теперь вы готовы реализовать обратный вызов датчика onSensorChanged (), чтобы реагировать на эти обновления датчиков.

Шаг 4: Внедрение обратного вызова onSensorChanged()

Большая часть интересного кода для обновлений датчиков происходит в обратном вызове onSensorChanged(). Здесь нам нужно, чтобы представление реагировало на изменения датчика. Мы зарегистрировались для нескольких различных типов изменений, поэтому этот метод можно вызвать для любого изменения сенсора. На данный момент мы просто хотим сэкономить данные датчика, которые изменились, а затем заставить просмотр обновить его содержимое. Мы можем сделать это, просто аннулируем представление и заставляя его перерисовывать.

Шаг 5: Пользовательский накладной и основная деятельность

Теперь вам нужно добавить свой пользовательский вид в элемент управления FrameLayout. Для этого обновите метод onCreate() класса ArtutActivity. Добавьте следующий код чуть ниже вызова addView (), который добавляет ArDisplayView:

Это складывает два вида: сначала класс просмотра предварительного просмотра камеры, называемый ArDisplayView, а затем накладывает OverlayView, который отображает данные датчика поверх него. Если вы запустите приложение сейчас, действие запустится, и вы увидите предварительный просмотр камеры на экране с данными датчиков, отображаемыми поверх него (помните, что вы не можете делать снимки экрана камеры, поэтому на следующем рисунке показано только содержимое наложения) ,

Если вы используете приложение в данный момент, вы, вероятно, заметили, что данные датчиков обновляются очень быстро, несмотря на то, что они требуют достаточно медленной скорости, чтобы работать с изменениями ориентации. Эти датчики устройства имеют очень высокую степень чувствительности. В конечном итоге это приведет к шаткости в пользовательском интерфейсе. В конце концов, нам нужно будет реализовать некоторые алгоритмы сглаживания, чтобы удержать дрожи, когда мы начнем использовать данные датчиков в нашем приложении.

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

  • Числа акселерометра находятся в единицах СИ (м/с^2, т. е. В метрах в секунду, где гравитация Земли составляет 9,81 м/с^2).
  • Магнитные датчики находятся в микро-Тесласе. Когда они входят в формы x, y и z, мы можем измерить вектор и сравнить с гравитацией, чтобы определить, где (магнитный) север по отношению к устройству.
  • Гироскоп измеряет вращение вокруг каждой оси в радианах в секунду. Это также можно использовать для расчета относительной ориентации устройства.

Заключение

Это завершает первую часть нашего учебника AR. Расширенная реальность — захватывающий жанр для приложений на платформе Android. Android SDK предоставляет все необходимое для разработки гладких и интересных AR-приложений, но не все устройства могут удовлетворить требованиям к оборудованию, требуемым этими приложениями. К счастью, новейшее поколение Android-устройств является самым мощным, но многие из Android-устройств прекрасно способны работать с расширенными AR-приложениями.

В следующей части этой серии мы перейдем к сбору данных о местоположении и размещению объектов AR на экране в определенном месте. Это будет включать в себя различные математические алгоритмы, но конечным результатом будет . увеличение!

Andro >

класс 1-активити2
Есть ListView с элементами.
При нажатии на элемент происходит переходит на соответствующую активити, но сейчас всё работает на костылях (костыли и велосипеды. программируем как умеем), т.е. под каждый элемент сделано своё активити.

класс2-активити2
(в активити TextView)
.
классN-активитиN

Вопрос:
Как получить доступ к активити другого класса?
Т.е. будет 2 класса(содержащий lv и класс содержищий данные о выбранном элементе).
И из первого класса будут задаваться значения для другого.

.
switch (position) <
case 0:
//задаём значение tv из class1 для активити привязанного к class2
Intent intent =new Intent (class1.this, class2.class )
startActivity(intent);
break;
case1:
//задаём значение всё того же tv
.
>

В гугле не забанили. Ничего толкового не нашел.

Операции

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

Как правило, приложение состоит из нескольких операций, которые слабо связаны друг с другом. Обычно одна из операций в приложении обозначается как «основная», предлагаемая пользователю при первом запуске приложения. В свою очередь, каждая операция может запустить другую операцию для выполнения различных действий. Каждый раз, когда запускается новая операция, предыдущая операция останавливается, однако система сохраняет ее в стеке («стек переходов назад»). При запуске новой операции она помещается в стек переходов назад и новая операция отображается для пользователя. Стек переходов назад работает по принципу «последним вошёл — первым вышел», поэтому после того как пользователь завершил текущую операцию и нажал кнопку Назад, текущая операция удаляется из стека (и уничтожается), и возобновляется предыдущая операция. (Подробные сведения о стеке переходов назад представлены в статье Задачи и стек переходов назад.)

Когда операция останавливается по причине запуска новой операции, для уведомления об изменении ее состояния используются методы обратного вызова жизненного цикла операции. Существует несколько таких методов, которые может принимать операция вследствие изменения своего состояния — создание операции, ее остановка, возобновление или уничтожение системой; также каждый обратный вызов представляет возможность выполнить определенное действие, подходящее для соответствующего изменения состояния. Например, в случае остановки операция должна освободить любые крупные объекты, например, подключение к сети или базе данных. При возобновлении операции вы можете повторно получить необходимые ресурсы и возобновить выполнение прерванных действий. Такие изменения состояния являются частью жизненного цикла операции.

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

Создание операции

Чтобы создать операцию, сначала необходимо создать подкласс класса Activity (или воспользоваться существующим его подклассом). В таком подклассе необходимо реализовать методы обратного вызова, которые вызывает система при переходе операции из одного состояния своего жизненного цикла в другое, например при создании, остановке, возобновлении или уничтожении операции. Вот два наиболее важных метода обратного вызова:

onCreate() Этот метод необходимо обязательно реализовать, поскольку система вызывает его при создании вашей операции. В своей реализации вам необходимо инициализировать ключевые компоненты операции. Наиболее важно именно здесь вызвать setContentView() для определения макета пользовательского интерфейса операции. onPause() Система вызывает этот метод в качестве первого признака выхода пользователя из операции (однако это не всегда означает, что операция будет уничтожена). Обычно именно здесь необходимо применять любые изменения, которые должны быть сохранены помимо текущего сеанса работы пользователя (поскольку пользователь может не вернуться назад).

Существуют также и некоторые другие методы обратного вызова жизненного цикла, которые необходимо использовать для того, чтобы обеспечить плавный переход между операциями, а также для обработки непредвиденных нарушений в работе операции, в результате которых она может быть остановлена или даже уничтожена. Более подробное описание всех методов обратного вызова жизненного цикла представлены в разделе, посвященном управлению жизненным циклом операций.

Реализация пользовательского интерфейса

Для реализации пользовательского интерфейса операции используется иерархия представлений—объектов, полученных из класса View . Каждое представление отвечает за определенную область окна операции и может реагировать на действия пользователей. Например, представлением может быть кнопка, нажатие на которую приводит к выполнению определенного действия.

В Android предусмотрен набор уже готовых представлений, которые можно использовать для создания дизайна макета и его организации. Виджеты — это представления с визуальными (и интерактивными) элементами, например, кнопками, текстовыми полями, чекбоксами или просто изображениями. Макеты — это представления, полученные из класса ViewGroup , обеспечивающие уникальную модель компоновки для своих дочерних представлений, таких как линейный макет, сетка или относительный макет. Также можно создать подкласс для классов View и ViewGroup (или воспользоваться существующими подклассами), чтобы создать собственные виджеты и макеты, и затем применить их к макету своей операции.

Чаще всего для задания макета с помощью представлений используется XML-файл макета, сохраненный в ресурсах приложения. Таким образом вы можете хранить дизайн пользовательского интерфейса отдельно от исходного кода, который служит для задания поведения операции. Чтобы задать макет в качестве пользовательского интерфейса операции, можно использовать метод setContentView() , передав в него идентификатор ресурса для макета. Однако вы также можете создать новые View в коде вашей операции и создать иерархию представлений. Для этого вставьте View в ViewGroup , а затем используйте этот макет, передав корневой объект ViewGroup в метод setContentView() .

Подробные сведения о создании пользовательского интерфейса см. в статье Пользовательский интерфейс.

Объявление операции в манифесте

Чтобы операция стала доступна системе, ее необходимо объявить в файле манифеста. Для этого откройте файл манифеста и добавьте элемент в качестве дочернего для элемента . Например:


Существует несколько других атрибутов, которые можно включить в этот элемент, чтобы определить такие свойства, как метка операции, значок операции или тема оформления для пользовательского интерфейса операции. Единственным обязательным атрибутом является android:name — он определяет имя класса операции. После публикации вашего приложения вам не следует переименовывать его, поскольку это может нарушить некоторые функциональные возможности приложения, например, ярлыки приложения (ознакомьтесь с публикацией Вещи , которые нельзя менять в блоге разработчиков).

Дополнительные сведения об объявлении операции в манифесте см. в справке по элементу .

Использование фильтров намерений

При создании нового приложения с помощью инструментов Android SDK в заготовке операции, создаваемой автоматически, имеется фильтр намерений, который объявляет операцию. Эта операция реагирует на выполнение «основного» действия, и ее следует поместить в категорию переходсредства запуска. Фильтр намерений выглядит следующим образом.

Если приложение планируется создать самодостаточным и запретить другим приложениям активировать его операции, то других фильтров намерений создавать не нужно. В этом случае только в одной операции должно иметься «основное» действие, и ее следует поместить в категорию средства запуска, как в примере выше. В операциях, которые не должны быть доступны для других приложений, не следует включать фильтры намерений. Вы можете самостоятельно запустить такие операции с помощью явных намерений (как описывается в следующем разделе).

Однако, если вам необходимо, чтобы операция реагировала на неявные намерения, получаемые от других приложений (а также из вашего приложения), для операции необходимо определить дополнительные фильтры намерений. Для каждого типа намерения, на который необходимо реагировать, необходимо указать объект , включающий элемент и необязательный элемент или (или оба этих элемента). Эти элементы определяют тип намерения, на который может реагировать ваша операция.

Дополнительные сведения о том, как операции могут реагировать на намерения, приведены в статье Намерения и фильтры намерений.

Запуск операции

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

При работе с собственным приложением зачастую требуется лишь запустить нужную операцию. Для этого необходимо создать намерение, которое явно определяет требуемую операцию с помощью имени класса. Ниже представлен пример запуска одной операцией другой операции с именем SignInActivity .

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

Дополнительный компонент EXTRA_EMAIL , добавленный в намерение, представляет собой строковый массив адресов электронной почты для отправки письма. Когда почтовая программа реагирует на это намерение, она считывает дополнительно добавленный строковый массив и помещает имеющиеся в нем адреса в поле получателя в окне создания письма. При этом запускается операция почтовой программы, а после того, как пользователь завершит требуемые действия, возобновляется ваша операция.

Запуск операции для получения результата

В некоторых случаях после запуска операции может потребоваться получить результат. Для этого вызовите метод startActivityForResult() (вместо startActivity() ). Чтобы получить результат после выполнения последующей операции, реализуйте метод обратного вызова onActivityResult() . По завершении последующей операции она возвращает результат в объекте Intent в вызванный метод onActivityResult() .

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

В этом примере демонстрируется базовая логика, которой следует руководствоваться при использовании метода onActivityResult() для обработки результата выполнения операции. Первое условие проверяет, успешен ли запрос, и если он успешен, то результат для resultCode будет RESULT_OK ; также проверяется, известен ли запрос, для которого получен этот результат, и в этом случае requestCode соответствует второму параметру, отправленному в метод startActivityForResult() . Здесь код обрабатывает результат выполнения операции путем запроса данных, возвращенных в Intent (параметр data ).

При этом ContentResolver выполняет запрос к поставщику контента, который возвращает объект Cursor , обеспечивающий считывание запрошенных данных. Дополнительные сведения представлены в статье Поставщики контента.

Дополнительные сведения об использовании намерений см. в статье Намерения и фильтры намерений.

Завершение операции

Для завершения операции достаточно вызвать ее метод finish() . Также для завершения отдельной операции, запущенной ранее, можно вызвать метод finishActivity() .

Примечание. В большинстве случаев вам не следует явно завершать операцию с помощью этих методов. Как указано в следующем разделе, посвященном управлению жизненным циклом операции, система Android выполняет такое управление за вас, поэтому вам не нужно завершать ваши собственные операции. Вызов этих методов может отрицательно сказаться на ожидаемом поведении приложения. Их следует использовать исключительно тогда, когда вы абсолютно не хотите, чтобы пользователь возвращался к этому экземпляру операции.

Управление жизненным циклом операций

Управление жизненным циклом операций путем реализации методов обратного вызова имеет важное значение при разработке надежных и гибких приложений. На жизненный цикл операции напрямую влияют его связи с другими операциями, его задачами и стеком переходов назад.

Существует всего три состояния операции:

Возобновлена Операция выполняется на переднем плане экрана и отображается для пользователя. (Это состояние также иногда называется «Выполняется».) Приостановлена На переднем фоне выполняется другая операция, которая отображается для пользователя, однако эта операция по-прежнему не скрыта. То есть поверх текущей операции отображается другая операция, частично прозрачная или не занимающая полностью весь экран. Приостановленная операция полностью активна (объект Activity по-прежнему находится в памяти, в нем сохраняются все сведения о состоянии и информация об элементах, и он также остается связанным с диспетчером окон), однако в случае острой нехватки памяти система может завершить ее. Остановлена Операция полностью перекрывается другой операцией (теперь она выполняется в фоновом режиме). Остановленная операция по-прежнему активна (объект Activity по-прежнему находится в памяти, в нем сохраняются все сведения о состоянии и информация об элементах, но объект больше не связан с диспетчером окон). Однако операция больше не видна пользователю, и в случае нехватки памяти система может завершить ее.

Если операция приостановлена или полностью остановлена, система может очистить ее из памяти путем завершения самой операции (с помощью метода finish() ) или просто завершить ее процесс. В случае повторного открытия операции (после ее завершения) ее потребуется создать полностью.

Реализация обратных вызовов жизненного цикла

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

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

Вместе все эти методы определяют весь жизненный цикл операции. С помощью реализации этих методов можно отслеживать три вложенных цикла в жизненном цикле операции:

    Весь жизненный цикл операции происходит между вызовом метода onCreate() и вызовом метода onDestroy() . Ваша операция должна выполнить настройку «глобального» состояния (например, определение макета) в методе onCreate() , а затем освободить все оставшиеся в onDestroy() ресурсы. Например, если в вашей операции имеется поток, выполняющийся в фоновом режиме, для загрузки данных по сети, операция может создать такой поток в методе onCreate() , а затем остановить его в методе onDestroy() .

Видимый жизненный цикл операции происходит между вызовами методов onStart() и onStop() . В течение этого времени операция отображается на экране, где пользователь может взаимодействовать с ней. Например, метод onStop() вызывается в случае, когда запускается новая операция, а текущая больше не отображается. В промежутке между вызовами этих двух методов можно сохранить ресурсы, необходимые для отображения операции для пользователя. Например, можно зарегистрировать объект BroadcastReceiver в методе onStart() для отслеживания изменений, влияющих на пользовательский интерфейс, а затем отменить его регистрацию в методе onStop() , когда пользователь больше не видит отображаемого. В течение всего жизненного цикла операции система может несколько раз вызывать методы onStart() и onStop() , поскольку операция то отображается для пользователя, то скрывается от него.

Жизненный цикл операции, выполняемый на переднем плане, происходит между вызовами методов onResume() и onPause() . В течение этого времени операция выполняется на фоне всех прочих операций и отображается для пользователя. Операция может часто уходить в фоновый режим и выходить из него — например, метод onPause() вызывается при переходе устройства в спящий режим или при появлении диалогового окна. Поскольку переход в это состояние может выполняться довольно часто, код в этих двух методах должен быть легким, чтобы не допустить медленных переходов и не заставлять пользователя ждать.

На рисунке 1 иллюстрируются проходы и пути, которые операция может пройти между состояниями. Прямоугольниками обозначены методы обратного вызова, которые можно реализовать для выполнения действий между переходами операции из одного состояния в другое.

Рисунок 1. Жизненный цикл операции.

Эти же методы жизненного цикла перечислены в таблице 1, в которой подробно описан каждый метод обратного вызова и указано его место в жизненном цикле операции в целом, включая сведения о том, может ли система завершить операцию по завершении метода обратного вызова.

Таблица 1. Сводные сведения о методах обратного вызова жизненного цикла операции.

Метод Описание Завершаемый? Следующий
onCreate() Вызывается при первом создании операции. Здесь необходимо настроить все обычные статические элементы — создать представления, привязать данные и т. д. Этот метод передает объект Bundle, содержащий предыдущее состояние операции (если такое состояние было зафиксировано ранее; см. раздел Сохранение состояния операции).


За ним всегда следует метод onStart() .

Нет onStart()
onRestart() Вызывается после остановки операции непосредственно перед ее повторным запуском.

За ним всегда следует метод onStart() .

Нет onStart()
onStart() Вызывается непосредственно перед тем, как операция становится видимой для пользователя.

За ним следует метод onResume() , если операция переходит на передний план, или метод onStop() , если она становится скрытой.

Нет onResume()
или
onStop()
onResume() Вызывается непосредственно перед тем, как операция начинает взаимодействие с пользователем. На этом этапе операция находится в самом верху стека операций, и в нее поступают данные, вводимые пользователем.

За ним всегда следует метод onPause() .

Нет onPause()
onPause() Вызывается, когда система собирается возобновить другую операцию. Этот метод обычно используется для записи несохраненных изменений в постоянное место хранения данных, остановки анимаций и других элементов, которые могут использовать ресурсы ЦП и т. д. Здесь крайне важна оперативность, поскольку следующая операция не будет возобновлена до тех пор, пока она не будет возвращена на передний план.

За ним следует либо метод onResume() , если операция возвращается на передний план, либо метод onStop() , если операция становится скрытой для пользователя.

Да onResume()
или
onStop()
onStop() Вызывается в случае, когда операция больше не отображается для пользователя. Это может произойти по причине того, что операция уничтожена, или ввиду возобновления поверх нее другой операции (существующей или новой).

За ним следует либо метод onRestart() , если операция возобновляет взаимодействие с пользователем, либо метод onDestroy() , если операция переходит в фоновый режим.

Да onRestart()
или
onDestroy()
onDestroy() Вызывается перед тем, как операция будет уничтожена. Это финальный вызов, который получает операция. Его можно вызвать либо по причине завершения операции (вызов метода finish() ), либо ввиду временного уничтожения системой этого экземпляра операции с целью освободить место. Чтобы различить эти два сценария, используется метод isFinishing() . Да Ничего

В столбце «Завершаемый?» указывается, может ли система в любое время завершить процесс, содержащий операцию, после возвращения метода без выполнения другой строки кода операции. Для трех методов в этом столбце указано «Да»: ( onPause() , onStop() и onDestroy() ). Поскольку метод onPause() является первым из этих трех после создания операции, метод onPause() является последним, который гарантированно будет вызван перед тем, как процесс можно будет завершить; если системе потребуется срочно восстановить память в случае аварийной ситуации, то методы onStop() и onDestroy() вызвать не удастся. Поэтому следует воспользоваться onPause() , чтобы записать критически важные данные (такие как правки пользователя) в хранилище постоянных данных. Однако следует внимательно подходить к выбору информации, которую необходимо сохранить во время выполнения метода onPause() , поскольку любая блокировка процедур в этом методе может вызвать блокирование перехода к следующей операции и тормозить работу пользователя.

Методы, для которых в столбце Завершаемый? указано «Нет», защищают процесс, содержащий операцию , от завершения сразу с момента их вызова. Поэтому завершить операцию можно в период между возвратом onPause() и вызовом onResume() . Его снова не удастся завершить, пока снова не будет вызван и возвращен onPause() .

Примечание. Операцию, которую технически невозможно завершить в соответствии с определением в таблице 1, по-прежнему может завершить система, однако это может произойти только в чрезвычайных ситуациях, когда нет другой возможности. Случаи, когда возможно завершение операции, более подробно рассматриваются в статьеПроцессы и потоки.

Сохранение состояния операции

В обзорных сведениях об управлении жизненным циклом операции кратко упоминается, что в случае приостановки или полной остановки операции ее состояние сохраняется. Это действительно так, поскольку объект Activity при этом по-прежнему находится в памяти , и вся информация о ее элементах и текущем состоянии по-прежнему активна. Поэтому любые вносимые пользователем в операции изменения сохраняются, и когда операция возвращается на передний план (когда она «возобновляется»), эти изменения остаются в этом объекте.

Однако когда система уничтожает операцию в целях восстановления памяти, объект Activity уничтожается, в результате чего системе не удается просто восстановить состояние операции для взаимодействия с ней. Вместо этого системе необходимо повторно создать объект Activity , если пользователь возвращается к нему. Но пользователю неизвестно, что система уже уничтожила операцию и создала ее повторно, поэтому, возможно, он ожидает, что операция осталась прежней. В этой ситуации можно обеспечить сохранение важной информации о состоянии операции путем реализации дополнительного метода обратного вызова, который позволяет сохранить информацию о вашей операции: onSaveInstanceState() .

Прежде чем сделать операцию доступной для уничтожения, система вызывает метод onSaveInstanceState() . Система передает в этот метод объект Bundle , в котором можно сохранить информацию о состоянии операции в виде пар «имя-значение», используя для этого такие методы, как putString() и putInt() . Затем, если система завершает процесс вашего приложения и пользователь возвращается к вашей операции, система повторно создает операцию и передает объект Bundle в оба метода: onCreate() и onRestoreInstanceState() . С помощью любого из этих методов можно извлечь из объекта Bundle сохраненную информацию о состоянии операции и восстановить ее. Если такая информация отсутствует, то объект Bundle передается с нулевым значением (это происходит в случае, когда операция создается в первый раз).

Рисунок 2. Два способа возврата операции к отображению для пользователя в неизмененном состоянии: уничтожение операции с последующим ее повторным созданием, когда операция должна восстановить свое ранее сохраненное состояние, или остановка операции и ее последующее восстановление в неизмененном состоянии.

Примечание. Нет никаких гарантий, что метод onSaveInstanceState() будет вызван до того, как ваша операция будет уничтожена, поскольку существуют случаи, когда нет необходимости сохранять состояние (например, когда пользователь покидает вашу операцию нажатием кнопки Назад, явным образом закрывая ее). Если система вызывает метод onSaveInstanceState() , она делает это до вызова метода onStop() и, возможно, перед вызовом метода onPause() .

Однако, даже если вы ничего не предпринимаете и не реализуете метод onSaveInstanceState() , часть состояния операции восстанавливается реализацией по умолчанию метода onSaveInstanceState() класса Activity . В частности, реализация по умолчанию вызывает соответствующий метод onSaveInstanceState() для каждого объекта View в макете, благодаря чему каждое представление может предоставлять ту информацию о себе, которую следует сохранить. Почти каждый виджет в платформе Android реализует этот метод необходимым для себя способом так, что любые видимые изменения в пользовательском интерфейсе автоматически сохраняются и восстанавливаются при повторном создании операции. Например, виджет EditText сохраняет любой текст, введенный пользователем, а виджет CheckBox сохраняет информацию о том, был ли установлен флажок. От вас требуется лишь указать уникальный идентификатор (с атрибутом android:id ) для каждого виджета, состояние которого необходимо сохранить. Если виджету не присвоен идентификатор, то системе не удастся сохранить его состояние.

Вы также можете явно отключить сохранение информации о состоянии представления в макете. Для этого задайте для атрибута android:saveEnabled значение «false» или вызовите метод setSaveEnabled() . Обычно отключать сохранение такой информации не требуется , однако это может потребоваться в случаях, когда восстановить состояние пользовательского интерфейса операции необходимо другим образом.

Несмотря на то что реализация метода onSaveInstanceState() по умолчанию позволяет сохранить полезную информацию о пользовательском интерфейсе вашей операции, вам по-прежнему может потребоваться переопределить ее для сохранения дополнительной информации. Например, может потребоваться сохранить значения элементов, которые изменялись в течение жизненного цикла операции (которые могут коррелировать со значениями, восстановленными в пользовательском интерфейсе, однако элементы, содержащие эти значения пользовательского интерфейса, по умолчанию не были восстановлены).

Поскольку реализация метода onSaveInstanceState() по умолчанию позволяет сохранить состояние пользовательского интерфейса, в случае , если вы переопределите метод с целью сохранить дополнительную информацию о состоянии, перед выполнением каких-либо действий вы всегда можете вызвать реализацию суперкласса для метода onSaveInstanceState() . Точно так же реализацию суперкласса onRestoreInstanceState() следует вызывать в случае ее переопределения, чтобы реализация по умолчанию могла сохранить состояния представлений.

Примечание. Поскольку вызов метода onSaveInstanceState() не гарантируется, вам следует использовать его только для записи переходного состояния операции (состояние пользовательского интерфейса) — никогда не используйте его для хранения постоянных данных. Вместо этого используйте метод onPause() для сохранения постоянных данных (например, тех, которые следует сохранить в базу данных), когда пользователь покидает операцию.

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

Обработка изменений в конфигурации

Некоторые конфигурации устройств могут изменяться в режиме выполнения (например, ориентация экрана, доступность клавиатуры и язык). В таких случаях Android повторно создает выполняющуюся операцию (система сначала вызывает метод onDestroy() , а затем сразу же вызывает метод onCreate() ). Такое поведение позволяет приложению учитывать новые конфигурации путем автоматической перезагрузки в приложение альтернативных ресурсов, которые вы предоставили (например, различные макеты для разных ориентаций и экранов разных размеров).

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

Лучший способ обработки такого перезапуска — сохранить и восстановить состояние операции с помощью методов onSaveInstanceState() и onRestoreInstanceState() (или onCreate() ), как описано в предыдущем разделе.

Дополнительные сведения об изменениях конфигурации, происходящих в режиме выполнения, и о способах их обработки представлены в руководствеОбработка изменений в режиме выполнения.

Согласование операций

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

Порядок обратных вызовов жизненного цикла четко определен, в частности, когда в одном и том же процессе находятся две операции , и одна из них запускает другую. Ниже представлен порядок выполнения действий в случае, когда операция А запускает операцию Б.

  1. Выполняется метод onPause() операции А.
  2. Последовательно выполняются методы onCreate() , onStart() и onResume() операции Б. (Теперь для пользователя отображается операция Б.)
  3. Затем, если операция A больше не отображается на экране, выполняется ее метод onStop() .

Такая предсказуемая последовательность выполнения обратных вызовов жизненного цикла позволяет управлять переходом информации из одной операции в другую. Например, если после остановки первой операции требуется выполнить запись в базу данных, чтобы следующая операция могла считать их, то запись в базу данных следует выполнить во время выполнения метода onPause() , а не во время выполнения метода onStop() .

Content and code samples on this page are subject to the licenses described in the Content License. Java is a registered trademark of Oracle and/or its affiliates.

Android Как вызвать функции в собственной библиотеке через интерфейс JNI


пример

Интерфейс Java Native (JNI) позволяет вам вызывать собственные функции из кода Java и наоборот. В этом примере показано, как загружать и вызывать собственную функцию через JNI, она не переходит к доступу к методам и полям Java из собственного кода с использованием функций JNI .

Предположим, у вас есть родная библиотека с именем libjniexample.so в libjniexample.so project/libs/ , и вы хотите вызвать функцию из класса JNITest Java внутри пакета com.example.jniexample .

В классе JNITest объявите функцию следующим образом:

В вашем собственном коде определите функцию следующим образом:

Аргумент pEnv является указателем на среду JNI, которую вы можете передать функциям JNI для доступа к методам и полям объектов и классов Java. thiz указатель является jobject ссылки на объект Java , который нативный метод был вызван (или класс , если это статический метод).

В вашем Java-коде в JNITest загрузите библиотеку следующим образом:

Обратите внимание на lib в начале, а .so в конце имени файла опущены.

Вызовите функцию native из Java следующим образом:

Запуск другой Activity — второго окна android-приложения

В этом уроке

Вы также должны прочитать

После завершения предыдущего урока, у вас есть приложение, которое показывает активити (один экран) с текстовым полем и кнопкой. В этом уроке вы добавим код к MainActivity , который запустит новую активити , когда пользователь нажмет на кнопку Отправить..

Ответить на кнопку Отправить

Чтобы ответить на событие нажатия кнопки, откройте fragment_main.xml файла макета и добавьте android:onClick атрибут к элементу:

android:onClick значение атрибута, «sendMessage» , это имя метода в вашей активити , который система вызывает когда пользователь нажимает кнопку.

Откройте MainActivity класс (расположенный в каталоге проекта src/ ) и добавьте соответствующий метод:

Чтобы система смогла найти этот метод с именем, заданным в android:onClick , сигнатура должна быть именно такой, как вы видели. В частности, метод должен:

  • Быть public
  • Имейте void в качестве возвращаемого значения
  • Иметь View в качестве единственного параметра (это будет View , на котором нажали)

Далее, вы заполните этот метод, чтобы прочитать содержимое текстового поля и доставить этот текст в другую активити .

Создать Intent

Intent это объект, который обеспечивает связывание отдельных компонент во время выполнения (например, двух активити ). Intent представляет «намерение что-то сделать». Вы можете использовать интент для широкого круга задач, но чаще всего они используются, чтобы начать другую активити .

Внутри sendMessage() метода, создайте Intent для запуска активити под названием DisplayMessageActivity :

Для этого требуется импортировать Intent класс:

Полезный совет: В Eclipse, нажмите Ctrl + Shift + O для импортирования недостающих классов (Cmd + Shift + O на Mac). В Android Studio команда для импорта Alt+Enter.

Конструктор, используемый здесь принимает два параметра:

  • Context в качестве первого параметра( this используется, поскольку Activity класс является подклассом Context )
  • Class компонента приложения, в который система должна доставить Intent (в данном случае активность, которая должна быть запущена)

Отправка intent в другие приложения

Intent, созданный в этом уроке считается явным, поскольку Intent указывает точный компонент приложения, в которое интент следует отправить. Тем не менее, интенты также могут быть неявными, в этом случае Intent не указывает нужный компонент, позволяя любой программе установленной ​​на устройстве отвечать на интенты, пока она удовлетворяет спецификациям мета-данных действия, задаваемыми в различных Intent параметрах. Для получения дополнительной информации читайте курс Взаимодействие с другими приложениями.

Примечание: Ссылка на DisplayMessageActivity вызовет ошибку, если вы используете интегрированную среду разработки, такую как Eclipse например, потому что класс еще не существует. Игнорируйте ошибку на данный момент; вы скоро создадите класс.

Intent не только позволяет начать другую Activity, но также может выполнять связь данных в Activity. В sendMessage() методе, используйте findViewById() для получения EditText элемента и добавьте его текстовое значение в Intent:

Примечание: Вам необходим оператор импорта для android.widget.EditText . Вы определите EXTRA_MESSAGE константу буквально сейчас.

Intent может нести коллекцию различных типов данных в виде пары ключ-значение, называемых Extras. Метод putExtra() принимает имя ключа в первом параметре и значение во втором параметре.

Для того, чтобы Activity смогла запросить дополнительные данные, вы должны определить ключ для дополнений вашего интента, используя общедоступную константу. Так что добавьте EXTRA_MESSAGE определение в начало MainActivity класса:

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

Запуск второй Activity

Для запуска активити, вызовите startActivity() и передайте в него ваш Intent . Система получает этот вызов и запускает экземпляр Activity указанный в Intent .


С помощью этого нового кода, полный sendMessage() метод, который вызывается кнопкой Отправить теперь выглядит следующим образом:

Теперь вам нужно создать DisplayMessageActivity класс для того, чтобы это работало.

Создание второй Activity

Для создания новой Activity в Android Studio:

В главном меню выберите File>New>Activity>Blank Activity.

Заполните поля в окне мастера создания активити:

  • Activity Name: DisplayMessageActivity
  • Layout Name: activity_display_message
  • Title: Моё сообщение
  • Hierarchial Parent: com.example.myfirstapp.MainActivity

Остальные поля оставьте по умолчанию. Нажмите Finish.

Для создания новой Activity в Eclipse:

  • Нажмите New на панели инструментов.
  • В появившемся окне, откройте Android папку и выберите Android Activity. Нажмите Next.
  • Выберите BlankActivity и нажмите Next.
  • Заполните информацию о Activity:
    • Project: MyFirstApp
    • Activity Name: DisplayMessageActivity
    • Layout Name: activity_display_message
    • Fragment Layout Name: fragment_display_message
    • Title: Моё сообщение
    • Hierarchial Parent: com.example.myfirstapp.MainActivity
    • Navigation Type: None

    Нажмите Finish.

Рисунок 1. Мастер новой активити в Eclipse.

Если вы используете инструменты командной строки, создайте новый файл с именем DisplayMessageActivity.java в проекте в src/ каталоге, рядом с оригиналом MainActivity.java файлом.

Откройте DisplayMessageActivity.java файл. Если вы использовали Android Studio или Eclipse для создания этой Activity:

  • Класс уже включает в себя реализацию требуемого onCreate() метода. Вы обновите реализацию этого метода позже.
  • Есть также реализация onCreateOptionsMenu() метода, но вам это не будет нужно в данном приложении, так что вы можете удалить его.
  • Есть также реализация onOptionsItemSelected() , который обрабатывает поведение панели действий для кнопки Вверх . Оставьте его как есть.
  • Может быть также PlaceholderFragment класс, который расширяет Fragment . Вам не нужен будет этот класс в окончательном варианте этой активити .

Фрагменты разбивают функциональность приложений и пользовательский интерфейс на модули, которые можно будет повторно использовать. Для более подробной информации о фрагментах см.Руководство по Фрагментам. Окончательный вариант этой активити не использует фрагменты.

Примечание: Ваша активити может выглядеть иначе, если вы не использовали последнюю версию ADT плагина. Убедитесь, что вы установили последнюю версию ADT плагина для завершения этого курса.

DisplayMessageActivity класс должен выглядеть следующим образом:

Реализация Custom View-компонента в Android

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

Если какая-то специфичная особенность, из тех которые просит заказчик, требует особые функциональные возможности, которые невозможно сделать с помощью встроенных в Android View-компонентов, тогда нужно реализовывать собственный View-компонент (Custom View). Это не значит, что нужно всё взять и бросить, просто потребуется некоторое время на его реализацию, к тому же это довольно интересный и увлекательный процесс.

Я недавно попал в похожую ситуацию: мне нужно было создать индикатор страниц для Android ViewPager. В отличи от iOS, Android не предоставляет такой View-компонент, поэтому мне пришлось делать его самому.

Я потратил довольно много времени на его реализацию. К счастью, этот Custom View-компонент можно использовать и в других проектах, поэтому чтобы сэкономить личное время и время других разработчиков, я решил оформить всё это дело в виде библиотеки. Если вам нужен похожий функционал и не хватает времени на его реализацию собственными силами, можете взять его с этого GitHub репозитория.

Рисуем!

Так как в большинстве случаев разработка Custom View-комопонента занимает больше времени, чем работа с обычными View-компонентами, создавать их целесообразно только тогда, когда нет более простого способа реализовать специфичную особенность, или когда у вас есть ниже перечисленные проблемы, которые Custom View-компонент может решить:

  • Производительность. Если у вас есть много View-компонентов в одном layout-файле и вы хотите оптимизировать это с помощью создания единственного Custom View-компонента;
  • Большая иерархия View-компонентов, которая сложна в эксплуатации и поддержке;
  • Полностью настраиваемый View-компонент, которому нужна ручная отрисовка;

Если вы ещё не пробовали разрабатывать Custom View, то эта статья — отличная возможность окунуться в эту тему. Здесь будет показана общая структура View-компонента, как реализовывать специфичные вещи, как избежать распространённые ошибки и даже как анимировать ваш View-компонент!

Первая вещь, которую нам нужно сделать, это погрузиться в жизненный цикл View. По какой-то причине Google не предоставляет официальную диаграмму жизненного цикла View-компонента, это довольно распространённое среди разработчиков непонимание, поэтому давайте рассмотрим её.

Constructor

Каждый View-компонент начинается с Constructor’а. И это даёт нам отличную возможность подготовить его, делая различные вычисления, устанавливая значения по умолчанию, ну или вообще всё что нам нужно.


Но для того чтобы сделать наш View-компонент простым в использовании и установке, существует полезный интерфейс AttributeSet. Его довольно просто реализовать и определённо стоит потратить на это время, потому что он поможет вам (и вашей команде) в настройке вашего View-компонента с помощью некоторых статических параметров на последующих экранах. Во-первых, создайте новый файл и назовите его «attrs.xml». Этот файл может содержать все атрибуты для различных Custom View-компонентов. Как вы можете видеть в этом примере есть View-компонент названный PageIndicatorView и один атрибут piv_count.

Во-вторых, в конструкторе вашего View-компонента, вам нужно получить атрибуты и использовать их как показано ниже.

  • При создании кастомных атрибутов, добавьте простой префикс к их имени, чтобы избежать конфликтов имён с другими View-компонентами. Обычно добавляют аббревиатуру от названия View-компонента, поэтому у нас префикс «piv_»;
  • Если вы используете Android Studio, то Lint будет советовать вам использовать метод recycle() до тех пор пока вы сделаете это с вашими атрибутами. Причина заключается в том, что вы можете избавиться от неэффективно связанных данных, которые не будут использоваться снова;

onAttachedToWindow

После того как родительский View-компонент вызовет метод addView(View), этот View-компонент будет прикреплён к окну. На этой стадии наш View-компонент будет знать о других View-компонентах, которые его окружают. Если ваш View-компонент работает с View-компонентами пользователя, расположенными в том же самом «layout.xml» файле, то это хорошее место найти их по идентификатору (который вы можете установить с помощью атрибутов) и сохранить их в качестве глобальной ссылки (если нужно).

onMeasure

Этот метод означает, что наш Custom View-компонент находится на стадии определения собственного размера. Это очень важный метод, так как в большинстве случаев вам нужно определить специфичный размер для вашего View-компонента, чтобы поместиться на вашем макете.

При переопределении этого метода, всё что вам нужно сделать, это установить setMeasuredDimension(int width, int height).

При настройке размера Custom View-компонента вы должны обработать случай, когда у View-компонента может быть определённый размер, который пользователь (прим. переводчика: программист работающий с вашим View-компонентом) будет устанавливать в файле layout.xml или программно. Для вычисления этого свойства, нужно проделать несколько шагов:

  • Рассчитать размер необходимый для содержимого вашего View-компонента (ширину и высоту);
  • Получить MeasureSpec вашего View-компонента (ширину и высоту) для размера и режима;
  • Проверить MeasureSpec режим, который пользователь устанавливает и регулирует (для ширины и высоты);

Посмотрите на значения MeasureSpec:

  1. MeasureSpec.EXACTLY означает, что пользователь жёстко задал значения размера, независимо от размера вашего View-компонента, вы должны установить определённую ширину и высоту;
  2. MeasureSpec.AT_MOST используется для создания вашего View-компонента в соответствии с размером родителя, поэтому он может быть настолько большим, насколько это возможно;
  3. MeasureSpec.UNSPECIFIED — на самом деле размер обёртки View-компонента. Таким образом, с этим параметром вы можете использовать желаемый размер, который вы расчитали выше.

Перед установкой окончательных значений в setMeasuredDimension, на всякий случай проверьте эти значения на отрицательность Это позволит избежать любых проблем в предпросмотре макета.

onLayout

Этот метод позволяет присваивать размер и позицию дочерним View-компонентам. У нас нет дочерних View-компонентов, поэтому нет смысла переопределять этот метод.

onDraw

Вот здесь происходит магия. Два объекта, Canvas и Paint, позволяют вам нарисовать всё что вам нужно. Экземпляр объекта Canvas приходит в качестве параметра для метода onDraw, и по существу отвечает за рисование различных фигур, в то время как объект Paint отвечает за цвет этой фигуры. Простыми словами, Canvas отвечает за рисование объекта, а Paint за его стилизацию. И используется он в основном везде, где будет линия, круг или прямоугольник.

Создавая Custom View-компонент, всегда учитывайте, что вызов onDraw занимает довольно много времени. При каких-то изменениях, сроллинге, свайпе вы будете перерисовывать. Поэтому Andorid Studio рекомендует избегать выделение объекта во время выполнения onDraw, вместо этого создайте его один раз и используйте в дальнейшем.

  • При отрисовке, имейте в виду переиспользование объектов вместо создания новых. Не полагайтесь на вашу IDE, которая должна подсветить потенциальную проблему, а сделайте это самостоятельно, потому что IDE может не увидеть этого, если вы создаёте объекты внутри методов вызываемых в onDraw;
  • Во время отрисовки, не задавайте размер прямо в коде. Обрабатывайте случай, когда у других разработчиков может быть тот же самый View-компонент, но с другим размером, поэтому делайте ваш View-компонент зависимым от того размера, который ему присвоен;

View Update

Из диаграммы жизненного цикла View-компонента, вы можете заметить что существует два метода, которые заставляют View-компонент перерисовываться. Методы invalidate() и requestLayout() могут помочь вам сделать ваш Custom View-компонент интерактивным, что собственно поможет изменять его внешний вид во время выполнения. Но почему их два?

Метод invalidate() используется когда просто нужно перерисовать View-компонент. Например, когда ваш View-компонент обновляет свой текст, цвет или обрабатывает прикосновение. Это значит, что View-компонент будет вызывать только метод onDraw, чтобы обновить своё состояние.

Метод requestLayout(), как вы можете заметить будет производить обновление View-компонента через его жизненный цикл, только из метода onMeasure(). А это означает, что сразу после обновления View-компонента вам нужно его измерить, чтобы отрисовать его в соответствии с новыми размерами.

Animation

Анимации в Custom View-компонентах, это по кадровый процесс. Это означает, что если вы например захотите сделать анимированным процесс изменения радиуса круга от маленького к большому, то вам нужно увеличивать его последовательно и после каждого шага вызывать метод invalidate для отрисовки.

Ваш лучший друг в анимации Custom View-компонентов — это ValueAnimator. Этот класс будет помогать вам анимировать любые значения от начала до конца и даже обеспечит поддержку Interpolator (если нужно).

Не забывайте вызывать метод Invalidate каждый раз, когда изменяется значение анимации.

Надеюсь, что эта статья поможет вам сделать свой первый Custom View-компонент. Если вы захотите получить больше информации по этой теме, то может посмотреть хорошее видео.

Установка Android Studio, настройка SDK

Для того чтобы писать приложения для OS Android вам понадобится установить среду разработки Android Studio(далее в тексте AS ). Вы спросите, почему именно AS а не Eclipse? Среда разработки Eclipse работает намного быстрее, и весит меньше, чем Android Studio,

но Google «рекомендует» использовать AS, так как в будущем он перестанет(вернее уже) перестал ее поддерживать. За Android Studio будущее, так сказать. У вас должен быть достаточно мощный компьютер, желательно x64 разрядный, так как AS использует около 3 ГБ оперативной памяти, добавьте сюда еще 3 ГБ на эмулятор андроид устройства. На моем ПК установлена win 8.1 pro x64, двуядерный процессор Intel 3.3 ГГц, с 8 ГБ оперативной памяти, и я чувствую себя вполне свободно.

Установка Android Studio, настройка SDK

Заходим на официальный сайт по ссылке https://developer.android.com/studio, качаем последнюю версию необходимой разрядности. На сегодня актуальная версия android-studio-2-1-2,

весить она будет примерно 1,2 Гб. Так что запаситесь терпением, если у вас медленный интернет.

После загрузки запустим программу установки android-studio-2-1-2.exe,

мастер установки пошагово предложит определить состав установки,

выбрать место установки,

жмем далее, пока на кнопке не появится надпись Install.

Снова ждем окончания установки.

После этого запустим Android Studio с рабочего стола, или из меню,

и нажмем кнопку Configure для настройки SDK. Вы увидите список установленных версий android,

под которые можете создавать приложения, желательно чтоб они были все. Если какие то версии не установлены, то жмем на ссылку Launch Standalone SDK Manager для установки и обновления пакетов.

Откроется менеджер SDK,

поставьте галочки на те пункты, которые необходимо, как узнать на какие именно? Менеджер SDK вам в этом поможет, отметив необходимые пакеты версий. Затем нажмите на кнопку в правом нижнем углу с надписью Instal 1 (1..100) package..

В вашем случае количество пакетов будет другое. Если вы лично, или то место где вы проживаете, находится под «западными санкциями», то для обновления пакетов, зайдите в меню Tools->Options.

где можно указать адрес и порт прокси сервера,

для обхода всяких ограничений ;-).

После обновлений можно закрыть менеджер SDK, и приступить к созданию приложения для Android.

В этом видео подробно показано как установить Andro >

Рекомендуем смотреть видео в полноэкранном режиме, в настойках качества выбирайте 1080 HD, не забывайте подписываться на канал в YouTube, там Вы найдете много интересного видео, которое выходит достаточно часто. Приятного просмотра!

Понравилась статья? Поделиться с друзьями:
Все языки программирования для начинающих