How to create a simple Scala SBT application for Android

Good day, friends. While developing tools for developers, I came across a question about the interaction of the aforementioned tool, programming language and platform. If the first two entities are simply created for each other (SBT is the main, most often used build tool for development on Scala), then their applicability to the Andriod platform is not for granted. Nevertheless, in a huge and constantly evolving software industry, there are situations when this set of technologies will be a rational choice. The question is when this choice is rational, is not the subject of this article. And I’ll tell you exactly how to do it.

Development environment


I investigated the applicability of this approach to work in Android Studio and IntelliJ IDEA . For this purpose, there is practically no significant difference in the environments. There are nuances - with them I will acquaint you in the course of the article. But in general, the technologies that we will use are equally integrated both in the Studio and in the Idea. After all, the first is based on the same IntelliJ platform as the Idea. Therefore, your choice should rather be based on the specifics of the project.

Creating a basic project


The first tool in our business will be the Scala plugin , designed for development in the Scala language in IntelliJ IDEA and Android Studio. This plugin also provides SBT. It does not come with development environments, so we need to download it from the JetBrains repository.


Now we can create a basic Scala SBT project. And here we have the first difference between the media: Scala plugin provides a wizard (Wizard) to create a new project SBT available in the Idea: [File → New → Project → Scala → SBT]. But Android Studio does not give us the opportunity to choose the Wizard and immediately launches its own (based on another build tool - Gradle). Therefore, we can only import a project into SBT Studio. Basically, this is a matter of 20 seconds:

  1. In a separate folder we create a file build.sbtwith the contents name := "example".

  2. With the console team, sbt compilewe generate everything you need for a basic project. (the terminal is launched inside the Studio to have access to SBT)



  3. In the welcome window of Android Studio, do the Import project and select the one we created build.sbt

In the import wizard, specify the Android SDK (currently 25), remove the add-on check boxes. action and import. In the Idea, when creating a new SBT project, there is no way to select the Android SDK - select the Java SDK (currently 1.8) and the Scala 2.11. * Version. And the Android SDK itself will subsequently be substituted after turning on the Android Framework. SBT project is ready.

Plugin for integrating SBT and Android


Next, you need to adapt the project to run on the Android platform.

  1. First of all, add the projectfile to the folder plugins.sbtand add the plugin to it

    addSbtPlugin("org.scala-android" % "sbt-android" % "1.7.7")

  2. We modify build.sbtby adding a build-plug insertion procedure sbt-android and TASK to run

    name := "example"
    scalaVersion := "2.11.8"
    enablePlugins(AndroidApp)
    run <<= run in Android
    install <<= install in Android

  3. Add to the project AndroidManifest.xml. In Studio, you can put this file in the root of the project. In the Idea, because the wizard has already created a folder structure; put it on the same level as the Source root folder, i.e. c src/main. After creating the file, Idea / Studio will tell us to include the Android Framework in the project. We accept the offer. Minimum manifest completion:


  4. If we work in Android Studio, we create the source root directory scr (in the Idea already exists src/main/scala). In it, we create the com.example package with a file MyActivity.scala, with a simple Activity

    package com.example
    import android.app.Activity
    class MyActivity extends Activity { }

  5. Open and turn on the Android emulator
  6. Refresh the project to activate all the new settings. If you work in IDEA, then with this action, ProGuard (which we will talk about later) is automatically turned on. Now it should be disabled in [Project Structure → Facets → Android → Proguard → Run proguard ...].
  7. And run the default run configuration [Run -> Run ... -> MyActivity

Result:



ProGuard Tool - Adapting Scala to Android


At the moment, we have the simplest application running. If we begin to expand it, for example, at least add to build.sbtthe Scaloid library (which we will talk about later)

libraryDependencies += "org.scaloid" %% "scaloid" % "4.2"

we’ll run into a problem. Android platform has a limit on the number of references - 64K. Due to the nature of Scala code, this limit is reached quickly. And just by turning on this library we get an error when starting the project:

Error:Android Pre Dex: [scaloid_2.11-4.2.jar] trouble writing output: Too many method references: 81694; max is 65536.

Standard approach to solving this problem:

  1. Cutting out unused code from a project using the ProGuard tool ;
  2. Separation of project sources into several .dex files, each of which will contain an acceptable number of methods. The name of the procedure is MultiDexing .

As a rule, if the problem can be solved only by the first step, then only it is used. A MultiDexing is already if the first is not enough. Within this task, ProGuard will be enough.
Is included in the tool options Facet's All Android: [Project Structure → Facets → Android → Proguard → Run proguard ...]. Note that, by default, a text file with basic settings is already specified: Studio includes a file from the SDK .../Android/sdk/tools/proguard/proguard-android.txt, Idea includes and creates a configuration file in the root of the project .../example/proguard-sbt.txt. For the successful execution of our project, it will be enough to add three additional options to it:

-dontwarn scala.**
-dontwarn org.scaloid.**
-keep class com.example.**

When processing the bytecode of the Scala and Scaloid libraries, ProGuard will pour Warnings, which in our case do not affect the result, but block the further launch process. Therefore, the option -dontwarnwe remove them. Also, you must specify that ProGuard does not cut out our handwritten code. This provides an option -keep class.

When I started, I encountered two errors:

  1. Unsupported class version number [52.0] (maximum 51.0, Java 1.7). Its reason is that the Android SDK is based on Java 1.8, and ProGuard supports a maximum of 1.7. This is solved by updating ProGuard to version 5 and higher, right inside the Android SDK;
  2. Error:ProGuard: Cannot find file /Users/.../Caches/AndroidStudio2.3/compile-server/.../proguard.txt- this is a bug of the platform itself, and it is solved by manually or scripting a file lining proguard-android.txtfrom the Android SDK to the same cache, followed by renaming to proguard.txt. Not the most convenient way, but still, this procedure is not often used, especially because users usually specify all these options in the build.sbtfile.

I did not observe any more problems, and successfully launched the project with the Scaloid library included in it, which was cut by ProGuard at startup. To achieve a certain project complexity, it makes sense to include a plug-in for working with ProGuard in it. There are several of them, but at the moment, I found one: sbt-proguard . According to ProGuard himself, there is also a manual on his website.

On this, friends, I will complete this article. If it causes interest, I will study and describe in more detail the use of libraries for development for Android on Scala, such as Scaloid or Macroid , and how, using the features of the Scala language, to solve common tasks / problems on this mobile platform. In many ways, they helped me in studying the material.Android SBT plugin resource and just an informational site dedicated to development on Scala for Android. Thank you for your attention, I will be once constructive criticism, questions, comments and suggestions. Thanks!

Also popular now: