Пишем приложение для Android на Ruby (Ruboto)

от автора

Появилась у меня как-то идея(или расcчётка по мобильным платформам) написать приложения под android на своём любимом ruby. И тут я вспомнил про проект который несколько раз упоминался в RubyNoName подкасте, собственно речь пойдёт о Ruboto.


Ну что ж приступим. Для программирования нам понадобится:

  1. JDK
  2. Android SDK
  3. JRuby
  4. Gem Ruboto

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

ruboto gen app --package ru.nitrodev.demo_app 

Переходим в директорию demo_app и любуемся заботливо подготовленной структурой приложения. В папке src уже лежит наше первое активити, собственно к нему мы и перейдём.
В качестве примера разберу такие базовые вещи как:

  1. Создание интерфейса
  2. Воспроизведение аудио с помощью MediaPlayer
  3. Создание активити
  4. Определение координат касания экрана
  5. Работа с Intent (открытие страницы, набор номера)
  6. Создание меню

Пойдём по порядку.

Создание интерфейса

В любом приложении нам понадобится интерфейс, мы можем использовать стандартный способ создания интерфейса с помощью XML ресурса, но тогда мы теряем всю гибкость ruby. Поэтому интерфейс будем описывать в коде, для этого мы можем вызывать Android API или использовать ruboto/widget.rb который является обвёрткой над API и предоставляет простой DSL для создания интерфейса.
Рассмотрим сначала первый способ на примере создания LinearLayout содержащего одно текстовое поле и 4 кнопки.
Первым делом импортируем нужные компоненты интерфейса

java_import "android.widget.Button" java_import "android.widget.TextView" java_import "android.widget.LinearLayout" 

Описываем сам интерфейс

 ll = LinearLayout.new(@ruboto_java_instance)   ll.orientation = LinearLayout::VERTICAL    tv = TextView.new(@ruboto_java_instance)   tv.text = "Прощай Java"   ll.add_view tv #Добавляем наще TextView в LinearLayout   params = tv.get_layout_params   params.width = ViewGroup::LayoutParams::MATCH_PARENT    btn1 = Button.new(@ruboto_java_instance)   btn1.text = "Play"   btn1.on_click_listener = proc{ Play }    ll.add_view btn1   params = search_b.get_layout_params   params.width = ViewGroup::LayoutParams::MATCH_PARENT    btn2 = Button.new(@ruboto_java_instance)   btn2.text = "Pause"   btn2.on_click_listener = proc{ Pause }    ll.add_view btn2   params = search_b.get_layout_params   params.width = ViewGroup::LayoutParams::MATCH_PARENT    btn3 = Button.new(@ruboto_java_instance)   btn3.text = "Второй экран"   btn3.on_click_listener = proc{ twoActivity }    ll.add_view btn3   params = search_b.get_layout_params   params.width = ViewGroup::LayoutParams::MATCH_PARENT    btn4 = Button.new(@ruboto_java_instance)   btn4.text = "Третий экран"   btn4.on_click_listener = proc{ threeActivity }    ll.add_view btn4   params = search_b.get_layout_params   params.width = ViewGroup::LayoutParams::MATCH_PARENT    setContentView ll 

Вы должны признать что данный код является таким же громоздким как java и вряд ли кому-то понравится в ruby сообществе. Более элегантным будет использовать DSL Ruboto. Рассмотрим аналогичный код использующий путь Ruboto.

ruboto_import_widgets :Button, :LinearLayout, :TextView self.content_view =     linear_layout :orientation => :vertical do       text_view :text => 'Только Ruby - только хардкор', :width => :match_parent       button :text => 'Play', :width => :match_parent, :on_click_listener => proc { play }       button :text => 'Pause', :width => :match_parent, :on_click_listener => proc { pause }       button :text => 'Второй эран', :width => :match_parent, :on_click_listener => proc { twoActivity }       button :text => 'Третий эран', :width => :match_parent, :on_click_listener => proc { threeActivity }     end 

Как видно колличество кода сократилось в 4-5 раз.
Результат этого кода

Воспроизведение аудио с помощью MediaPlayer

Для воспроизведения звука импортируем MediaPlayer и AudioManager

java_import "android.media.MediaPlayer" java_import "android.media.AudioManager" java_import "android.net.Uri"  

Затем получаем uri файла и создаём MediaPlayer

java_file = java.io.File.new("/mnt/sdcard/naive.mp3")     uri = Uri.fromFile(java_file)     @player = MediaPlayer.create(self, uri); 

Работать с нашим плеером можем стандартными функциями

@player.start @player.pause 

Создание активити

Остальные пункты нашего манула создадим в отдельных активити.
Основным способом создания RubotoActivity является использование start_ruboto_activity.
start_ruboto_activity — это эквивалент Android startActivity в Ruboto. Он имеет два обязательных параметр: строка содержащая глобальную ссылку на создаваемую активити и блок который будет выполняться один раз при создании активити.
Создадим вторую активити

start_ruboto_activity("$activity_two") do   def on_create(bundle)     super     setTitle 'Вторая активити'   end end 

Определение координат касания экрана

Отслеживание касания осуществляется с помощью функции on_touch_event данный метод является эквивалентом андроид метода onTouchEvent
Отслеживаем касание одним пальцем

def on_touch_event(event)     index = event.find_pointer_index(0)      x = event.getX(index)     y = event.getY(index)     toast "Position: #{x}, #{y}"   true end 

Работа с Intent

Для работы с Intent импортируем соответствующие Android API

java_import "android.content.Intent" 

Дальнейшая работа с Intent производится аналогично java

intent = Intent.new(Intent::ACTION_CALL)           intent.setData(Uri.parse("tel:5551234"))           startActivity(intent)  intent = Intent.new(Intent::ACTION_VIEW)           intent.setData(Uri.parse("http://ruboto.org/"))           startActivity(intent) 

Добавим соответствующие разрешения в AndroidManifest

<uses-permission android:name="android.permission.CALL_PHONE" /> 

Создание меню

Для работы с меню используется стандартный коллбек on_create_options_menu. Тут всё просто: создаём пункты меню и вешаем на них слушателя, при клике в toast будет выводиться сообщение с названием пункта меню.

def on_create_options_menu(menu)   m1 = menu.add('Action 1')   m1.set_on_menu_item_click_listener do |menu_item|     @text_view.text = menu_item_title     toast menu_item.title     true    end    m2 = menu.add('Action 2')   m2.set_on_menu_item_click_listener do |menu_item|     @text_view.text = menu_item.title     toast menu_item.title     true    end   true end 

Вот собственно и всё.
Весь данный код можно посмотреть на github
Ссылки для более глубокого погружения в Ruboto:
Wiki: github.com/ruboto/ruboto/wiki
Readme: github.com/ruboto/ruboto/blob/master/README.md
Отличная презентация с примерами: jay.mcgavren.com/files/presentations/ruboto/

ссылка на оригинал статьи http://habrahabr.ru/post/165071/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *