четверг, 19 июля 2012 г.

IDE Eclipse: разработка под Android


Оригинальная статья доступна на сайте www.smashingmagazine.com
Сегодня существует множество подходов к разработке мобильных приложений. Сложные аппаратные устройства, планшетные ПК и различные программные платформы (Symbian OS, iOS, WebOS, Windows Phone 7…) открывают бескрайнее пространство для разработчиков.
Итак, список приложений для начала разработки мобильных приложений огромен. Какую платформу выбрать? Какой язык программирования учить? Какой набор приложений выбрать для планирования проекта? В этом руководстве вы усвоите, как начать разработку мобильных приложений под Android, открытую мобильную ОС от Google.

Почему именно Android?

Android - открытая платформа, основанная на ядре Linux. Установлена она на тысячах девайсов широкого круга производителей. Android предоставляет приложения для всех видов оборудования, которые только можно представить в виде современных мобильных устройств - цифровые компасы, видеокамеры, GPS, датчики и многое другое.
Бесплатные инструменты разработки для Android SDKпозволяют быстро начать создание бесплатных или почти бесплатных приложений. Когда вы готовы явить миру вашу программку, вы можете опубликовать ее посредством Android Market. Публикация в Android Market требует одноразового регистрационного взноса (25 долл. США на момент написания статьи) и, в отличие от App Store Apple (который очень строго подходит к цензу), делает ваше приложение доступным для скачивания и покупки после быстрого обзора - если приложение не нарушает правила и закон.
Вот несколько других отличий Android SDK, которые предлагает Вам преимущества как разработчику:
  • Пакет Android SDK доступен для Windows, Mac и Linux, поэтому вам не нужно платить за новое "железо" для написания приложений.
  • SDK встроен в Java. Если вы знакомы с языком программирования Java, вы уже на полпути к освоению.
  • С учетом распространения приложения через Android Market, оно будет доступно сразу для сотен тысяч пользователей. Вы не ограничивается только официальным Market'ом, поскольку есть альтернативы. Например, вы можете опубликовать приложение на своем блоги. Amazon по слухам, готовит собственный магазин Android-приложений.
  • Равно как техническая документация SDK, для разработчиков Android создаются новые ресурсы. Платформа набирает все большую популярность среди пользователей и разработчиков.
Хватит говорить - давайте начнем разработку приложений для Android!

Установка Eclipse и Android SDK

Рекомендуемое окружение для разработки Android SDK приложений - это Eclipse с установленным плагином Android Development Toolkit (ADT). Я опишу все далее.
  • Скачайте Android SDK для вашей платформы (Windows, Mac OS X или Linux).
  • Распакуйте скачанные файлы в любое запоминающееся место на жестком диске (в Linux я придерживаюсь пути /opt/local/).
  • Если Eclipse уже установлен, скачайте и установите пакет Eclipse IDE for Java Developers. Для программирования Google рекомендует использовать Eclipse 3.5 (Galileo).
  • Запустите Eclipse и выберите Help->Install New Software.
  • Нажмите Add в окне Available Software.
  • Введите Android Development Tools в поле Name и https://dl-ssl.google.com/android/eclipse/ в поле Location.
  • Нажмите OK и проверьте Developer Tools в списке доступного ПО. Этим самым мы установим Android Development Tools и DDMS, отладочный инструмент для Android.
  • Install in Get Started Developing for Android with Eclipse
  • Нажмите Next и Finish для установки плагина. Нужно перезапустить Eclipse единожды после установки.
  • После перезапуска Eclipse выберите Window->Preferences, и вы увидите Android в списке категорий.
  • Теперь нужно указать Eclipse, где расположен установленный Android SDK. НажмитеAndroid, затем Browse для выбора местоположения распакованных файлов SDK. К примеру,/opt/local/android-sdk.


    Prefs in Get Started Developing for Android with Eclipse
  • Нажмите OK для запоминания Eclipse'ом расположения SDK.

Ориентация платформы Android

Перед тем, как начать написание приложений для Android, нужно скачать SDK для платформы Android. Каждая платформа имеет собственную версию Android SDK, которая установлена на устройствах пользователей. Для версии Android 1.5 и выше существует две платформы: Android Open Source Project и Google.
Android Open Source Project - платформа с открытым исходным кодом, но не включает в себя расширения Google, такие как Google Maps. Если вы не хотите использовать Google API, функциональность карт Google будет недоступна для вашего приложения. Если у вас нет особых причин делать это, я бы рекомендовал вам настроить таргетинг на одной из платформ Google, так как это позволит вам использовать собственные расширения Google.
  • Выберите Window->Android SDK and AVD Manager.
  • Нажмите Available Packagesв левой колонке и проверьте репозиторий, чтобы показать список доступных платформ Android.
  • Вы можете выбрать платформы для загрузки из списка или оставить все отмеченными, чтобы загрузить все доступные платформы. По завершению, нажмите Install Selected и следуйте инструкции по установке.
    Sdk in Get Started Developing for Android with Eclipse
После того как все было успешно загружено, вы готовы приступить к разработке для Android.

Создание нового проекта Android

Мастер настройки Eclipse New Project Wizard поможет создать приложение Android, сгенерировав файлы и код, готовые к запуску, справа от блока. Это быстрый способ убедиться в работоспособности и хорошая начальная точка при начале разработки приложений:
  • Выберите File->New->Project…
  • Выберите Android Project
  • В диалоге New Project введите следующие настройки:
    Project Name: BrewClock
    Build Target: Google Inc. 1.6 (Api Level 4)
    Application Name: BrewClock
    Package Name: com.example.brewclock
    Create Activity: BrewClockActivity
    Min SDK Version: 4
    Eclipse New Project Settings in Get Started Developing for Android with Eclipse
После нажатия Finish, Eclipse создаст новый проект Android, готовый к запуску. Помните, вы говорили Eclipse сгенерировать Activity, названный BrewClockActivity? Это код, который Android на самом деле использует для запуска приложения. Сгенерированный код будет отображен в виде простого сообщения в духе ‘Hello World’.

Пакеты

Имя пакета - идентификатор для вашего приложения. Когда настанет время публикации результата на Android Market, этот идентификатор будет использоваться для отслеживания обновлений для приложения, поэтому важно убедиться, что этот идентификатор уникален. Хотя здесь мы используем имя com.example.brewclock,для реального приложения лучше выбрать что-то вроде com.yourcompanyname.yourapplication.

Версии SDK

Версия Min SDK Version (название говорит само за себя) - самая ранняя версия Android, на которой приложение будет работать. С каждым новым выпуском Android, SDK добавляет и изменяет различные методы. При выборе версии SDK, Android (и Android Market) знает, что ваше приложение будет работать только на устройствах с версией Android указанной версии и выше.

Запуск вашего приложения

Сейчас попробуем запустить наше приложение в Eclipse. Поскольку это первый запуск, Eclipse спросит, с каким из типов проекта вы работаете:
  • Выберите Run->Run или нажмите Ctrl+F11.
  • Выберите Android Application и нажмите OK.
Eclipse попробует запустить приложение на устройстве с Android. На данный момент, однако, у вас нет устройств под управлением Android, так что запустить проект не удастся, и вам будет предложено создать новое устройство Android Virtual Device (AVD).
Eclipse No Avd in Get Started Developing for Android with Eclipse

Виртуальные устройства (Android Virtual Devices)

Android Virtual Device (AVD) эмулирует среду Android, будь то мобильный телефон или планшетный ПК. Вы можете создавать сколько угодно устройств AVD, с разными версиями платформы Android. Для каждого AVD вы можете настроить различные параметры устройств, указав наличие физической клавиатуры, поддержки GP, разрешение камеры и так далее.
Перед тем как запустить приложение, вы должны создать свой первое устройство AVD с платформой SDK (Google API, 1,6).
Давайте сделаем это сейчас:
  • Если вы еще не пробовали запустить приложение, нажмите Run (или сочетание клавишCtrl+F11)
  • Когда всплывает предупреждение, нажмите Yes для создания AVD.
  • Нажмите New в диалоге Android SDK and AVD Manager.
  • Установите следующие параметры для AVD:
    Name: Android_1.6
    Target: Google APIs (Google Inc.) - API Level 4
    SD Card Size: 16 MiB
    Skin Built In: Default (HVGA)
  • Нажмите Create AVD.
  • Закройте диалог Android SDK and AVD Manager.
Sdk Manager New Avd in Get Started Developing for Android with Eclipse

Запуск кода

Попробуйте запустить приложение снова (Ctrl + F11). Eclipse теперь будет создавать ваш проект и запускать новый AVD. Помните, AVD полностью эмулирует среду Android, причем вам даже не нужно наблюдать достаточно медленный процесс загрузки, как в случае с реальным устройством. По этой причине, как только AVD будет готов к работе, лучше не закрывать окно, пока вы закончили разработку, в течение всего дня.
Когда эмулятор загрузится, Eclipse автоматически установит и запустит приложение:
App Running-550-e1287474474253 in Get Started Developing for Android with Eclipse

Создание вашего первого приложения на Android

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

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

Одним из первых шагов к созданию какой-либо программы вообще - проектирование пользовательского интерфейса. Вот небольшой набросок нашего приложения:
Design Sketch in Get Started Developing for Android with Eclipse
Пользователь сможет установить время кипячения в минутах, используя кнопки + и -. Когда он нажмет Start, отсчет времени начнется в течение указанного количества минут. Если пользователь отменяет кипячение, нажав на кнопку еще раз, время будет увеличено, когда таймер достигнет 0.

Построение интерфейса

Пользовательский интерфейс Android, или оболочка, которые описаны в документации XML, могут быть найдены в папке res/layouts. Код шаблона, уже сгенерированный Eclipse, объявлен в res/layouts/main.xml и, как вы заметили, уже работает в эмуляторе.
Eclipse располагает собственным инструментарием для проектировки макета, который позволяет создавать интерфейс методом перетаскивания в пределах экрана. Тем не менее, временами легче написать интерфейс в XML и использовать графический макет для предварительного просмотра результатов.
Давайте сделаем это сейчас, изменив main.xml в соответствии с эскизом выше:
  • Откройте res/layouts/main.xml в Eclipse двойным нажатием из Package Explorer.
  • Выберите вкладку main.xml в нижней части экрана, чтобы перейти в режим XML.
Сейчас изменим содержание main.xml на следующее:
# /res/layouts/main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
  xmlns:android="http://schemas.android.com/apk/res/android"
  android:orientation="vertical"
  android:layout_width="fill_parent"
  android:layout_height="fill_parent">
  <LinearLayout
    android:orientation="horizontal"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:padding="10dip">
    <TextView
      android:layout_width="wrap_content"
      android:layout_height="wrap_content"
      android:textSize="20dip"
      android:text="Brews: " />
    <TextView
      android:layout_width="fill_parent"
      android:layout_height="wrap_content"
      android:text="None"
      android:gravity="right"
      android:textSize="20dip"
      android:id="@+id/brew_count_label" />
  </LinearLayout>
  <LinearLayout
    android:orientation="horizontal"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:layout_weight="1"
    android:gravity="center"
    android:padding="10dip">
    <Button
      android:id="@+id/brew_time_down"
      android:layout_width="wrap_content"
      android:layout_height="wrap_content"
      android:text="-"
      android:textSize="40dip" />
    <TextView
      android:id="@+id/brew_time"
      android:layout_width="wrap_content"
      android:layout_height="wrap_content"
      android:text="0:00"
      android:textSize="40dip"
      android:padding="10dip" />
    <Button
      android:id="@+id/brew_time_up"
      android:layout_width="wrap_content"
      android:layout_height="wrap_content"
      android:text="+"
      android:textSize="40dip" />
  </LinearLayout>
  <Button
    android:id="@+id/brew_start"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:layout_gravity="bottom"
    android:text="Start" />
</LinearLayout>
Как вы можете видеть, файлов в Android XML много, но это позволит вам контролировать практически каждый элемент на экране.
Одним из наиболее важных элементов интерфейса в Android являются контейнеры Layout, такие как LinearLayout, используемый в этом примере. Эти элементы невидимы для пользователя, но выступают в качестве контейнеров для других элементов, таких как Buttons иTextViews.
Есть несколько типов расположения макета, каждый из которых используется для построения различных типов планировки. Как и LinearLayout и AbsoluteLayoutTableLayout позволяет использование интерфейса с использованием сетки. Вы можете узнать больше об этом в общий макет объектов разделе API-документации.

Привязка вашего макета к коду

После сохранения макет, попробуйте запустить приложение в эмуляторе, нажав Ctrl + F11, или нажмите значок Run в Eclipse. Теперь вместо сообщения "Hello World" вы увидите, что в Android теперь отображается интерфейс приложения.
Если нажать любую кнопку, они будут подсвечиваться, как и ожидалось, но не делайте что-нибудь помимо этого. Давайте продолжим написание кода вслед за интерфейсом макета:
# /src/com/example/brewclock/BrewClockActivity.java
...
import android.widget.Button;
import android.widget.TextView;
 
public class BrewClockActivity extends Activity {
  /** Properties **/
  protected Button brewAddTime;
  protected Button brewDecreaseTime;
  protected Button startBrew;
  protected TextView brewCountLabel;
  protected TextView brewTimeLabel;
 
  ...
 }
Далее, мы изменим вызов onCreate. Это вызов происходит всякий раз, когда на Android запускается приложение. В коде, сгенерированном Eclipse, onCreateсоздает вид активности наR.layout.main. Это та строка кода, которая дает команду Android декодировать макет документа XML и отображать его пользователю.

Объект ресурса (Resource Object)

В Android, R - это специальный объект, который автоматически создается для обеспечения доступа к ресурсам вашего проекта (макеты, строки, меню, иконки...) внутри кода. Каждому ресурсу присваивается свой id. В файле макета (см. выше) это @+id атрибуты XML. Мы будем использовать их для привязки Buttons и TextViews в нашем макете:
# /src/com/example/brewclock/BrewClockActivity.java
...
public class BrewClockActivity extends Activity {
  ...
  public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);
 
    // Connect interface elements to properties
    brewAddTime = (Button) findViewById(R.id.brew_time_up);
    brewDecreaseTime = (Button) findViewById(R.id.brew_time_down);
    startBrew = (Button) findViewById(R.id.brew_start);
    brewCountLabel = (TextView) findViewById(R.id.brew_count_label);
    brewTimeLabel = (TextView) findViewById(R.id.brew_time);
  }
}

"Прослушка" событий

Для определения нажатия кнопок нам необходимо реализовать их прослушивание. Вы можете быть знакомы со слушателями обратного вызова, или callbacks, из других платформ, таких как Javascript / JQuery или Rails.
Android обеспечивает аналогичный механизм путем предоставления интерфейса Listener, такие как OnClickListener, которые определяют методы, которые будут срабатывать при возникновении события. OnClickListener интерфейс уведомит ваше приложение, когда пользователь нажимает на экран или определенную кнопку. Кроме того, необходимо сказать каждой кнопке о ClickListener:
# /src/com/example/brewclock/BrewClockActivity.java
...
// Be sure not to import
// `android.content.dialoginterface.OnClickListener`.
import android.view.View.OnClickListener; 
 
public class BrewClockActivity extends Activity
  implements OnClickListener {
  ...
  public void onCreate(Bundle savedInstanceState) {
    ...
    // Setup ClickListeners
    brewAddTime.setOnClickListener(this);
    brewDecreaseTime.setOnClickListener(this);
    startBrew.setOnClickListener(this);
  }
  ...
  public void onClick(View v) {
    // TODO: Add code to handle button taps
  }

}
Далее мы добавим код, который обрабатывает каждое из наших нажатий кнопок. Мы также добавим четыре новые свойства Activity, что позволит пользователю установить и отслеживать время пивоварения: сколько варок было сделано и запущен ли таймер.
# /src/com/example/brewclock/BrewClockActivity.java
...
public class BrewClockActivity extends Activity
  implements OnClickListener {
  ...
  protected int brewTime = 3;
  protected CountDownTimer brewCountDownTimer;
  protected int brewCount = 0;
  protected boolean isBrewing = false;
  ...
  public void onClick(View v) {
    if(v == brewAddTime)
      setBrewTime(brewTime + 1);
    else if(v == brewDecreaseTime)
      setBrewTime(brewTime -1);
    else if(v == startBrew) {
      if(isBrewing)
        stopBrew();
      else
        startBrew();
    }
  }
}
Обратите внимание, что мы используем CountDownTimer класс, предоставляемый Android. Это позволяет легко создать и запустить простой счетчик и получать уведомления через регулярные промежутки времени в то время, как идет обратный отсчет. Вы будете использовать это в методеstartBrew, читайте об этом ниже.
Следующие методы - модели поведения ползунка настройки времени варки, запуска и остановки варения, а также счетчика. Мы также инициализируем свойства brewTime иbrewCount в onCreate.
Было бы хорошей практикой переместить этот код в отдельный класс модели, но для простоты мы добавим код в BrewClockActivity:
# /src/com/example/brewclock/BrewClockActivity.java
...
public class BrewClockActivity extends Activity
  implements OnClickListener {
  ...
  public void onCreate(Bundle savedInstanceState) {
    ...
    // Set the initial brew values
    setBrewCount(0);
    setBrewTime(3);
  }
 
  /**
   * Set an absolute value for the number of minutes to brew.
   * Has no effect if a brew is currently running.
   * @param minutes The number of minutes to brew.
   */
  public void setBrewTime(int minutes) {
    if(isBrewing)
      return;
 
    brewTime = minutes;
 
    if(brewTime < 1)
      brewTime = 1;
 
    brewTimeLabel.setText(String.valueOf(brewTime) + "m");
  }
 
  /**
   * Set the number of brews that have been made, and update
   * the interface.
   * @param count The new number of brews
   */
  public void setBrewCount(int count) {
    brewCount = count;
    brewCountLabel.setText(String.valueOf(brewCount));
  }
 
  /**
   * Start the brew timer
   */
  public void startBrew() {
    // Create a new CountDownTimer to track the brew time
    brewCountDownTimer = new CountDownTimer(brewTime * 60 * 1000, 1000) {
      @Override
      public void onTick(long millisUntilFinished) {
        brewTimeLabel.setText(String.valueOf(millisUntilFinished / 1000) + "s");
      }
 
      @Override
      public void onFinish() {
        isBrewing = false;
        setBrewCount(brewCount + 1);
 
        brewTimeLabel.setText("Brew Up!");
        startBrew.setText("Start");
      }
    };
 
    brewCountDownTimer.start();
    startBrew.setText("Stop");
    isBrewing = true;
  }
 
  /**
   * Stop the brew timer
   */
  public void stopBrew() {
    if(brewCountDownTimer != null)
      brewCountDownTimer.cancel();
 
    isBrewing = false;
    startBrew.setText("Start");
  }
  ...
}
Только части этого кода, характерные для Android, создают отображения меток, используя метод setText. В startBrew мы создаем и запускаем CountDownTimer для начала посекундного отсчета, когда варка/кипячение окончео. Обратите внимание, что мы определяем слушателейCountDownTimer ( onTick и onFinish). onTick будет вызываться каждые 1000 миллисекунд (1 секунду), в то время как вызов onFinish происходит тогда, когда таймер достигнет нуля.

Избегаем сложности в написании кода

Чтобы сохранить это руководство простым, я намеренно применял надписи непосредственно в коде (например, "Brew Up!""Start""Stop"). На самом деле, это не очень хорошая практика, так как затрудняет поиск и изменение этих строк в крупных проектах.
Android обеспечивает аккуратный способ хранения ваших текстовых строк отдельно от кода R-объекта. R позволяет определить все строки приложения в XML-файле (res/values/strings.xml), к которому можно получить доступ в коде по ссылке. Например:
# /res/values/strings.xml
<string name="brew_up_label">Brew Up!</string>
...
 
# /res/com/example/brewclock/BrewClockActivity.java
...
brewLabel.setText(R.string.brew_up_label);
...
Теперь, если вы хотите изменить Brew Up! что-то другое, нужно изменить его единожды в файлеstrings.xml. Если ваше приложение содержит десятки файлов кода, надписей в одном месте приобретает огромный смысл!

ПРоверяем BrewClock

Мы завершили написание кода, и пришло время "опробовать" приложение. Нажмите "Run" илиCtrl + F11, чтобы запустить BrewClock в эмуляторе. Если все прошло хорошо, вы увидите интерфейс настройки и готовы к заварке чая! Попробуйте установить разное время заварки и нажмите Start для обратного отсчета.
App Finished-550-e1287474491689 in Get Started Developing for Android with Eclipse

Резюме

В этом кратком введении в to Android, вы установили Android SDK и плагин Eclipse Android Development Tools (ADT). Вы настроили эмулятор или виртуальное устройство для тестирования ваших приложений. Вы также создали рабочее приложение для Android который подчеркнул ряд ключевых понятий, которые вы будете использовать при разработке будущих Android приложений.
Будем надеяться, что это разбудит ваш аппетит для создания мобильных приложений и экспериментов в этой захватывающей области. Android предлагает отличный способ к написанию приложений для ряда нынешних и будущих мобильных устройств. Если вы уже написали рабочее приложение под эту платформу, не забудьте сообщить нам об этом в комментариях!
(ik), (vf)

Chris - ПО-разработчик, работающий с Ruby, Rails и Android. В 2010 году он основал Plymouth Software, где он проектирует и создает веб- и мобильные приложения. В перерывах между путешествиями и распитием чая, Chris пишет о программировании, дизайне и бизнесе на своем блоге chrisblunt.com.

Как разогнать эмулятор Android

Intel HAXM
Каждый, кто хоть раз работал с эмулятором для разработки приложений под Android, знает, что даже на современном железе эмулятор тормозит так, что для его использования нужно нечеловеческое терпение. То есть, наверное, надо самому стать андроидом-киборгом.

Но есть и еще один метод – попроще.
Intel Hardware Accelerated Execution Manager(Intel® HAXM) — это решение, использующее аппаратные возможности виртуализации (Intel® VT) и позволяющее значительно ускорить работу эмулятора Android. 

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

В случае разработки приложения, использующего только Dalvik разработчику не придется ничего менять, т.к. приложение не заметит разницы. В случае с NDK приложением необходимо будет добавить поддержку x86 архитектуры к списку собираемых библиотек. Сделать это несложно, нужно просто добавить поддержку x86 в make файл. 

Системные требования


  • Процессор с поддержкой VT-x, EM64T, Execute Disable Bit. Чтобы узнать поддерживает ли ваш процессор перечисленные возможности, можно воспользоваться сайтом ark.intel.com/
  • Как минимум 1 Гб, а лучше 2Гб оперативной памяти.

Поддерживаемые ОС


  • Windows 7 (32/64), Windows Vista* (32/64), Windows XP (32)
  • Mac OS X 10.6 и выше (32/64)
  • Ubuntu (64)

Установка


Intel HAXM можно установить как вручную, так и используя Android SDK Manager. 

Установка вручную


Зайдите на сайт software.intel.com/ru-ru/android/ и скачайте установочный пакет для вашей платформы. Далее запустите установку и следуйте подсказкам мастера установки. 

Установка с помощью Android SDK Manager




  1. Запустите Android SDK Manager
  2. В разделе Extras выберите «Intel Hardware Accelerated Execution Manager»
  3. Отметьте его галочкой и нажмите «Install package…»
  4. Далее подтвердите соглашение с лицензией и нажмите кнопку «Install»
  5. SDK Manager скачает и распакует пакет в каталог extras, находящийся в каталоге, в который был установлен Android SDK
  6. Перейдите в этот каталог и запустите установку Intel HAXM



Установка Intel HAXM


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



В процессе установки может возникнуть и такое



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

Для того, чтобы проверить, что все установлено верно и работает, необходимо в командной строке выполнить: 

sc query intelhaxm

После выполнения данной команды вы увидите текущий статус службы



Так же может пригодится способ остановить службу:

sc stop intelhaxm

Запустить службу:

sc start intelhaxm

Установка эмулятора Android x86


Описанное выше было не что иное, как подготовка почвы. Теперь необходимо установить сам эмулятор, который мы хотим «разогнать» с помощью Intel HAXM. В настоящий момент их два:

  • Android 4.0.3 (API 15)
  • Android 2.3.3 (API 10)

Устанавливаются они с помощью Android SDK Manager. Запускаем, отмечаем галочками интересующие нас образы и устанавливаем.



Создание виртуального устройства


После установки образа эмулятора Android для x86 необходимо создать новое виртуальное устройство с помощью Android Virtual Device Manager. Для этого:

  • Запускаем ADV Manager
  • Выбираем создание новойго устройства «New...»



  1. В окне свойств задаем произвольное название, например «Intel_Android»
  2. Выбираем версию, в моем случае версия «Android 4.0.3 – API Level 15»
  3. Устанавливаем остальные параметры (размер и наличие SD карты, разрешение и т.д.)
  4. Далее следует добавить обязательный параметр в раздел «Hardware» — «GPU Emulation» (кнопка «New», в списке «Property» необходимо выбрать «GPU Emulation», затем «ОК») и установить его в «yes»



Готово! Теперь осталось запустить и проверить все ли настроено верно. Выбираем созданный эмулятор и запускаем его кнопкой «Start». Далее идем в настройки и смотрим название устройства. Если все было сделано правильно, то для нашего примера, в поле «Model number» мы увидим строку «Android SDK Build for x86».



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

http://habrahabr.ru/post/111405/


  • Первый способ является оптимальным, когда вы используете один из стандартных View. У класса View существует метод SetOnTouchListener(View.OnTouchListener l), аргументом которого является класс, реализующий интерфейс OnTouchListener. Этот метод позволяет назначить «слушателя» MotionEvent'ов. Интерфейс OnTouchListener обязует класс реализовывать метод public boolean OnTouch(View v,MotionEvent event), вторым аргументом которого и является нужный нам MotionEvent. Теперь каждый раз, когда пользователь будет прикасаться к экрану, Android будет вызывать наш метод OnTouch, давая ему в аргумент описание произошедшего действия, то есть MotionEvent. Рассмотрим подробнее на примере:
    Вот наш файл res/layout/main.xml:

      1 <?xml version="1.0encoding="utf-8"?>
      2 <LinearLayout xmlns:android="schemas.android.com/apk/res/android"
      3     android:orientation="vertical"
      4     android:layout_width="fill_parent"
      5     android:layout_height="fill_parent"
      6     android:id="@+id/ll"
      7 >
      8 </LinearLayout>

    А вот наш Activity класс:

      1 import android.app.Activity;
      2 import android.os.Bundle;
      3 import android.util.Log;
      4 import android.view.MotionEvent;
      5 import android.view.View;
      6 import android.view.View.OnTouchListener;
      7 import android.widget.LinearLayout;
      8 
      9public class main extends Activity implements OnTouchListener{// Заставляем наш Activity класс воплощать интерфейс OnTouchListener
     10     /** Called when the activity is first created. */
     11     @Override
     12     public void onCreate(Bundle savedInstanceState) {
     13         super.onCreate(savedInstanceState);
     14         setContentView(R.layout.main);
     15         LinearLayout ll =(LinearLayout)this.findViewById(R.id.ll);//Достаем нужный View
     16        ll.setOnTouchListener(this);// Устанавливаем данный класс в качестве слушателя MotionEvent'ов для нашего LinearLayout
     17     }
     18 
     19     @Override
     20    public boolean onTouch(View v, MotionEvent event)// Вот, собственно, метод, который и будет обрабатывать MotionEvent'ы.
     21 {
     22         int Action=event.getAction();
     23// С помощью метода getAction() получаем тип действия(ACTION_DOWN,ACTION_MOVE или ACTION_UP)
     24         StringBuilder str=new StringBuilder();
     25         str.append("\nActrion type: ");
     26 //Дальше для лучшего восприятия(т.к. константы ACTION_DOWN,ACTION_MOVE и ACTION_UP числовые)
     27         //проводим switch по переменной Action и добавляем в наш StringBuilder название константы
     28         switch(Action)
     29         {
     30             case MotionEvent.ACTION_DOWN: str.append(«ACTION_DOWN\n»);break;
     31             case MotionEvent.ACTION_MOVE: str.append(«ACTION_MOVE\n»);break;
     32             case MotionEvent.ACTION_UP: str.append(«ACTION_UP\n»);break;
     33         }
     34 //С помощью методов getX() и getY() получаем координаты по оси x и y соответственно
     35         //Следует отметить, что точка 0 располагается в левом верхнем углу экрана.
     36         //Ось x направлена вправо
     37         //Ось y направлена вниз(чем ниже, тем больше координата).
     38        str.append(«Location: »).append(event.getX()).append(" x ").append(event.getY()).append("\n");//Узнаем координаты
     39        str.append(«Edge flags: »).append(event.getEdgeFlags()).append("\n");// Метод getEdgeFlags возвращает информацию о пересечении краев экрана
     40         str.append(«Pressure: »).append(event.getPressure()).append("\n");// Узнаем давление
     41        str.append(«Size: »).append(event.getSize()).append("\n"); // Узнаем размер указателя(места соприкосновения пальца с экраном)
     42        str.append(«Down time: »).append(event.getDownTime()).append(«ms\n»);// Узнаем время, когда палец был опущен на экран в миллисекундах
     43         str.append(«Event time: »).append(event.getEventTime()).append(«ms»);//узнаем текущее время(соответствующее обрабатываемому MotionEvent'у) в миллисекундах
     44         str.append(" Elapsed: ").append(event.getEventTime()-event.getDownTime());//Узнаем сколько времени прошло с момента опускания пальца, до текущего MotionEvent'а 
     45         Log.v(«Mytag», str.toString());//Для того, чтобы можно было отслеживать эти действия, записываем всю информацию о них в лог.
     46         return true;// Почему мы возвращаем true будет рассмотрено потом
     47     }
     48 }

    Понятно, что один класс может быть слушателем у нескольких View. Чтобы это учитывать метод onTouch принимает в аргумент View.
  • Второй способ является оптимальным, когда вы пишете свой View класс, который должен реагировать на прикосновения. У View есть метод onTouchEvent(MotionEvent event), который, собственно, и позволяет обрабатывать MotionEvent'ы. Рассмотрим на примере:
    Напишем свой класс SomeView:

      1 package com.example.MotionEventExample1;
      2 import android.content.Context;
      3 import android.util.AttributeSet;
      4 import android.util.Log;
      5 import android.view.MotionEvent;
      6 import android.view.View;
      7 
      8 public class SomeView extends View
      9 {
     10 //Сначала необходимо реализовать конструктор.
     11     //Тут все просто - просто вызываем конструктор суперкласса
     12     public SomeView(Context context, AttributeSet attrs)
     13     {
     14         super(context,attrs);
     15     }
     16    
     17     //Теперь приступаем непосредственно к обработке MotionEvent'ов.
     18     //Для этого нужно переписать метод onTouchEvent
     19     @Override
     20     public boolean onTouchEvent(MotionEvent event)
     21     {
     22        
     23         Float X=(Float)event.getX();
     24         Float Y=(Float)event.getY();
     25         int Action=event.getAction();
     26         String ActionString="";
     27         switch(Action)
     28         {
     29             case MotionEvent.ACTION_DOWN: ActionString=«ACTION_DOWN»;break;
     30             case MotionEvent.ACTION_MOVE: ActionString=«ACTION_MOVE»;break;
     31             case MotionEvent.ACTION_UP: ActionString=«ACTION_UP»;break;
     32         }
     33        Log.v(«MyTag»,«View OnTouchListener:\n»+«Coords: »+X.toString()+" x "+Y.toString()+"\nAction type: "+ActionString);
     34         return true;
     35     }
     36 
     37 }
     38 

    И наш /res/layout/main.xml:

      1 <?xml version="1.0encoding="utf-8"?>
      2 <LinearLayout xmlns:android="schemas.android.com/apk/res/android"
      3     android:orientation="vertical"
      4     android:layout_width="fill_parent"
      5     android:layout_height="fill_parent"
      6     >
      7 <com.example.MotionEventExample1.SomeView
      8     android:layout_width="fill_parent"
      9     android:layout_height="fill_parent"
     10     android:id="@+id/sv"
     11 />
     12 </LinearLayout>
     13 

    Activity класс:
      1 package com.example.MotionEventExample1;
      1 import android.app.Activity;
      2 import android.os.Bundle;
      3 
      4 public class main extends Activity {
      5     /** Called when the activity is first created. */
      6     @Override
      7     public void onCreate(Bundle savedInstanceState) {
      8         super.onCreate(savedInstanceState);
      9         setContentView(R.layout.main);
     10     }
     11 }


О том, что возвращают обработчики MotionEvent'ов


Как вы могли заметить, обработчики MotionEvent'ов должны возвращать boolean'овское значение. В примерах до этого мы просто всегда возвращали true. Так для чего же этим методам вообще нужно возвращать значение? Дело в том, что у одного View может быть несколько слушателей (например onTouchEvent в самом View и OnTouch у внешнего слушателя) и они имеют некоторый приоритет: OnTouch вызывается первым (если он вообще имеется), а уже после него может вызываться onTouchEvent. Вызов следующего по приоритету обработчика как раз зависит от возвращаемого текущим обработчиком значения (true — ничто не вызывается, false — вызывается следующий по приоритету, если таковой имеется). Таким образом Android позволяет нам разделять обязанности по обработке touch event'ов на несколько слушателей.

Drag and Drop

Вот мы и разобрались с основами обработки MotionEvento'ов. Для закрепления навыков напишем приложение, реализующее простенький Drag and Drop.

Вот наш /res/layout/main.xml:

  1 <?xml version="1.0encoding="utf-8"?> 
  2 <LinearLayout xmlns:android="schemas.android.com/apk/res/android
  3     android:orientation="vertical
  4     android:layout_width="fill_parent
  5     android:layout_height="fill_parent
  6     > 
  7 <com.example.dragdrop.SomeView 
  8     android:layout_width="fill_parent"  
  9     android:layout_height="fill_parent"  
 10     android:id="@+id/sv
 11 /> 
 12 </LinearLayout>

Вот наш Activity класс:

  1 package com.example.dragdrop; 
  2 
  3 import android.app.Activity; 
  4 import android.os.Bundle; 
  5 
  6 public class main extends Activity { 
  7     /** Called when the activity is first created. */ 
  8     @Override 
  9     public void onCreate(Bundle savedInstanceState) { 
 10         super.onCreate(savedInstanceState); 
 11         setContentView(R.layout.main); 
 12     } 
 13 }

А вот наш основной класс SomeView:

  1 package com.example.dragdrop; 
  2 
  3 import android.content.Context; 
  4 import android.graphics.Canvas; 
  5 import android.graphics.Color; 
  6 import android.graphics.Paint; 
  7 import android.graphics.Paint.Style; 
  8 import android.util.AttributeSet; 
  9 import android.view.MotionEvent; 
 10 import android.view.View; 
 11 
 12 public class SomeView extends View  
 13 
 14     Paint paint; 
 15     int X; 
 16     int Y; 
 17     final static int Radius=20
 18     public SomeView(Context context, AttributeSet attrs) 
 19     { 
 20         super(context, attrs); 
 21         paint = new Paint(); 
 22         paint.setColor(Color.YELLOW); 
 23         paint.setStyle(Style.FILL); 
 24         X=30
 25         Y=30
 26     } 
 27     @Override 
 28     public boolean onTouchEvent(MotionEvent event) 
 29     { 
 30         X=(int) event.getX(); 
 31         Y=(int) event.getY(); 
 32         return true
 33     } 
 34      
 35     @Override 
 36    protected void onDraw(Canvas canvas)// метод OnDraw вызвается Андроидом тогда, когда нужно отрисовать данный View
 37     { 
 38         canvas.drawCircle(X, Y, Radius, paint); 
 39        invalidate();// invalidate() нужен для того, чтобы оповестить Android, что нужно выполнить метод OnDraw снова, без него View не будет перериcовываться.
 40     } 
 41 
 42 }

Multitouch


В Android, сколько-бы вы пальцев ни использовали, информация о всех них хранится в одном MotionEvent'е. Первый метод, который нужно узнать, если вы собираетесь использовать мультитач — getPointerCount(), который возвращает количество пальцев, зафиксированных на экране(Не всегда совпадает с реальным количеством из-за ограничений в железе). Каждому пальцу, находящемуся на экране, присваивается индекс и id. Индексы всегда начинаются с 0, id — не обязательно. Для понятности рассмотрим на примере.
Первый палец опускается — ему присваивается index=0 и id=0
Второй палец опускается — ему присваивается index=1 и id=1
Первый палец поднимается — Второму пальцу присваивается index=0 (Индексы всегда начинаются с нуля), а id остается тем же
Второй палец поднимается — MotionEvent'ов больше нет, вплоть до следушего прикосновения.
Id всегда сохраняется за указателем(пальцем), так что мы всегда можем отследить какой угодно указатель.
Когда мы разобрались с id и индексами, рассмотрим как получать свойства (координаты, величину и т. п. ) у конкретного указателя, когда их много. Для этого в классе MotionEvent существуют методы:
  • getX(int Index)
  • getY(int Index)
  • getSize(int Index)
и т. д., мы уже их рассматривали
В аргумент эти методы принимают индекс указателя.
Но так как индексы указателя могут меняться, а часто требуется отследить конкретный палец, то существует очень важный метод  getPointerId(int index), который позволяет по указанному индексу узнать id указателя.

Рассмотрим пример: перепишем наше приложение (Drag and Drop) так, чтобы оно воспринимало мультитач.
(Важно: На эмуляторе мультитач не проверить, это можно сделать только на настоящем девайсе)
Вот наш res/layout/main.xml
  1 <?xml version="1.0encoding="utf-8"?> 
  2 <LinearLayout xmlns:android="schemas.android.com/apk/res/android
  3     android:orientation="vertical
  4     android:layout_width="fill_parent
  5     android:layout_height="fill_parent
  6     > 
  7 <com.example.multitouch.SomeView   
  8     android:layout_width="fill_parent"  
  9     android:layout_height="wrap_content"  
 10     android:id="@+id/view
 11     /> 
 12 </LinearLayout> 
 13 
Наш Activity класс:

  1 package com.example.multitouch; 
  2 
  3 import android.app.Activity; 
  4 import android.os.Bundle; 
  5 
  6 public class main extends Activity{ 
  7     /** Called when the activity is first created. */ 
  8     @Override 
  9     public void onCreate(Bundle savedInstanceState) { 
 10         super.onCreate(savedInstanceState); 
 11         setContentView(R.layout.main); 
 12     } 
 13 }

А вот основной класс — SomeView:
  1 package com.example.multitouch; 
  2 
  3 import android.content.Context; 
  4 import android.graphics.Canvas; 
  5 import android.graphics.Color; 
  6 import android.graphics.Paint; 
  7 import android.graphics.Paint.Style; 
  8 import android.util.AttributeSet; 
  9 import android.util.Log; 
 10 import android.view.MotionEvent; 
 11 import android.view.View; 
 12 
 13 //Будем рисовать желтые круги под пальцами 
 14 public class SomeView extends View  
 15 
 16     Paint paint;//нужен чтобы установить цвет. 
 17     int[] X; 
 18     int[] Y; 
 19     final static int Radius=20
 20     int PointerCount; 
 21     public SomeView(Context context, AttributeSet attrs) 
 22     { 
 23         super(context, attrs); 
 24         paint = new Paint(); 
 25         paint.setColor(Color.YELLOW); 
 26         paint.setStyle(Style.FILL); 
 27         PointerCount=0
 28         X=new int[10];//Это будут массивы координат(будем воспринимать до 10 пальцев) 
 29         Y=new int[10]; 
 30     } 
 31     @Override 
 32     public boolean onTouchEvent(MotionEvent event) 
 33     { 
 34         StringBuilder result=new StringBuilder(300); 
 35         PointerCount=event.getPointerCount(); 
 36         for(int i=0;i<PointerCount;i++) 
 37         { 
 38         int ptrId=event.getPointerId(i); 
 39         X[i]=(int) event.getX(i);// Запоминаем координаты 
 40         Y[i]=(int) event.getY(i); 
 41         result.append(«Pointer Index: »).append(i); 
 42         result.append(", Pointer Id: ").append(ptrId).append("\n"); 
 43         result.append(«Location: »).append(event.getX(i)); 
 44         result.append(" x ").append(event.getX(i)).append("\n"); 
 45         result.append(«Pressure: »).append(event.getPressure(i)); 
 46         result.append(«Size: »).append(event.getSize(i)).append("\n"); 
 47         } 
 48         Log.v(«Mytag», result.toString());//Выводим всю информацию в лог 
 49         return true
 50     } 
 51      
 52     @Override 
 53     protected void onDraw(Canvas canvas) 
 54     { 
 55         for(int i=0;i<PointerCount;i++)//Смотрим сколько пальцев было на экране и отрисовываем View 
 56         { 
 57         canvas.drawCircle(X[i], Y[i], Radius, paint); 
 58         } 
 59        invalidate();// invalidate() нужен для того, чтобы оповестить Android, что нужно выполнить метод OnDraw снова, без него View не будет перериовываться.
 60     } 
 61 
 62 
 63 

Другие способы взаимодействия с тачскрином


Взаимодействие с экраном через MotionEvent'ы является довольно низкоуровневым, нужно это прежде всего для разработки игр. Для более узких, повседневных ситуаций в Android предусмотрен ряд интерфейсов, которые позволяют распознавать наиболее «популярные» touch event'ы:
  • OnClickListener — onClick(View v)
  • OnFocusChangeListener — onFocusChange(View v, boolean hasFocus)
  • OnKeyListener — onKey(View v, int keyCode, KeyEvent event)
  • OnLongClickListener — onLongClick(View v)
и т. д.

Обрабатываются они аналогично, так что в пояснении не нуждаются.
Больше информации о таких методах можно узнать здесь:
developer.android.com/reference/android/view/View.html