Добавление поддержки Scala за несколько кликов в ваш Android-проект(Eclipse)

    В этом постеце на заметку я покажу как можно добавить в Eclipse, в существующий проект поддержку языка — Scala. И так, поехали!

    На хабре уже были посты на данную тематику. Например:
    вот этот
    Но душа всегда просит как можно более простого решения. В отличие от большинства способов, основанных на Ant или другом гемморое, который нужно проделать, чтобы добавить поддержку Scala, данный способ очень прост и быстр. А поможет нам в этом замечательный плагин к Eclipse — Treeshaker

    И так, что нужно сделать?
    Для тех, кто не хочет читать доку опишу установку и один нюанс, возникший у меня.

    • У вас уже должна быть настроена среда(Eclipse+плагин от гугла) для разработки под Андроид. Нужно установить плагин(Scala IDE). Заходим в пункт Eclipse Help->Install New Software, добавляем сайт к списку: download.scala-ide.org/releases-28/2.0.0-beta и жмем Next, ну и т.д.
    • Далее, по той же схеме как в пункте выше устанавливаем TreeShaker, а в качестве адреса сайта добавляем: treeshaker.googlecode.com/svn/trunk/update_site

    Вот и все! Мы установили все нужное.

    Теперь посмотрим как этим пользоваться.
    1. И так, создаем новый Андроид-проект
    2. Нажав правой кнопкой мыши на проект, в пункте Configure выбираем подпункт Add Scala Nature. И, о чудо! Scala — библиотеки добавились в проект
    3. Далее, снова нажимаем правой кнопкой мыши на проект и видим в списке пункт Add/Remove TreeShaker


    Далее, убираем наш ява-код, а вместо него вставляем следующий:
    import android.os.Bundle
    import android.view.View
    import android.widget.TextView
    import android.widget.Button
    import android.app.Activity
    import R._
     
    class ThreeShakerTutorialActivity extends Activity {
        lazy val textView = findViewById(R.id.text).asInstanceOf[TextView]
        lazy val button = findViewById(R.id.button).asInstanceOf[Button]
     
        override def onCreate(savedInstanceState: Bundle) {
            super.onCreate(savedInstanceState)
            setContentView(R.layout.main)
            button.setOnClickListener((v: View) => textView.setText("Hello Scala"))
        }
     
        implicit def func2OnClickListener(func: (View) => Unit) = {
            new View.OnClickListener() {
                override def onClick(v: View) = func(v)
        }   }
    }
    

    В макет main.xml, в LinearLayout добавляем Button и TextView c указанными в коде id-шниками(разметка есть в вики на гуглокоде, а я боюсь хабрапарсера). Все готово!

    Все бы хорошо, но есть одно НО. А именно, код

    button.setOnClickListener((v: View) => textView.setText("Hello Scala"))
    

    выдает ошибку компиляции. Исправляем так, но это плохой способ:
    button.setOnClickListener(func2OnClickListener((v: View) => textView.setText("Hello Scala")))
    


    А правильный такой, данный код оставляем как есть:
    button.setOnClickListener((v: View) => textView.setText("Hello Scala"))
    

    а вносим правку в определение метода:
    implicit def func2OnClickListener(func: (View) => Unit): View.OnClickListener = {
            new View.OnClickListener() {
                    override def onClick(v: View) = func(v)
            }
    }
    


    Спасибо хабраюзеру romik за эту подсказку.

    Хотя Scala я пока что не знаю на хорошем уровне, но интуиция — великая штука! Странно как-то, что авторы не заметили этот момент!
    Знающие люди могут объяснить почему там ошибка, но думаю авторы примера что-то явно забыли.

    Важно убедиться, чтобы в свойстве проекта Builders были все указанные ниже пункты:
    • Android Resource Manager
    • Android Pre Compiler
    • Scala Builder
    • Treeshaker
    • Android Package Builder

    Иначе, после компиляции и запуска проекта на эмуляторе будет эксепшн ClassNotFound.
    Демо проект — здесь
    Ads
    AdBlock has stolen the banner, but banners are not teeth — they will be back

    More

    Comments 11

      0
      Спасибо за обзор. Пригодится.
      По поводу «Исправляем так»: явное указание implicit функции все-таки моветон. Ошибка исправляется как-то по другому.
        0
        Будем знать. А почему же тогда ошибка вываливается?
        +1
        Попробуйте так:
        implicit def func2OnClickListener(func: (View) => Unit): View.OnClickListener = { ... }
          0
          Да, помогло. Спасибо!
          0
          Не собирали какие не будь бенчмарки? Понятно, что код будет медленне в общем случае. На сколько проект в размере увеличивается (туда должен быть включен компилятор и библиотека скалы)?
          Еще про версии: вы взяли бету 2ой версии, со стабильной не пробовали?
          http://download.scala-ide.org/releases-28/stable/site
            0
            Бенчмарк не собирал. Это нужно написать проектик посложнее, а моих знаний в скале не достаточно, да и времени не густо. Но определенно проект на скале под дроид будет! По размеру на примере хэллоу ворлда изменений нет. 20 кб. Но опять же, это хэллоу ворлд.
              0
              Компилятора в вашем apk-файле не будет, там должен находится только runtime. Плюс, после обработки proguard'ом размер абсолютно соизмерим с аналогичным Java-проектом.
                0
                Ок буду знать. Только не в моем apk файле (я разработкой под мобильники не занимаюсь).
                У меня такой интерес возник, в связи с тем, что н-р для web приложений включаются оба scala-compiler, и scala-library. Получается, что под андройдом нельзя во время исполнения выполнять scala выражения (twitter util-eval)?
                  +2
                  Боюсь, что нет, хотя не уверен. Runtime, который вкладывается в apk, специальный, scala-android, предназначенный для выполнения на Dalvik VM. Этот runtime нормально транслируется в dex-формат, а вот scala-compiler нет. Все от того, что Java на дроиде не совсем Java. Например, порт Google Guice — Roboguice идет без некоторых фич, касающихся AOP, потому, что Dalvik VM просто не реализует некоторый функционал, который есть у «большой» JVM.
                    0
                    Спасибо, за развернутый ответ.
              0
              А есть аналог TreeShaker под IntelliJ IDEA?

              Only users with full accounts can post comments. Log in, please.