📜 ⬆️ ⬇️

How to create a simple Scala SBT application for Android

Good day, friends. Being engaged in the development of tools for developers, I was faced with the question of the interaction of the above-mentioned tool, programming language and platform. If the first two entities are simply made for each other (SBT is the main, most used build tool for Scala development), their applicability to the Andriod platform is not something taken for granted. And yet, in a huge and constantly evolving software industry, there are also situations when this set of technologies will be a rational choice. The question - when this choice is rational, is not the subject of this article. And I will tell you exactly how to do it.

Development environment


I researched 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 - I will acquaint you with them 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 will need to download it from the JetBrains repository.
')

Now we can create a basic Scala SBT project. And here the first difference between environments takes place: Scala plugin provides a Wizard for creating a new SBT project, available in the Idea: [File → New → Project → Scala → SBT] . But Android Studio does not give us the opportunity to go to the choice of the Wizard and immediately runs its own (based on another build tool - Gradle). Therefore, we can only import the project into SBT Studio. In principle, this is a matter of 20 seconds:

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

  2. sbt compile console command, we generate everything you need for the base project. (the terminal is launched inside the Studio to have access to the SBT)



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

In the import wizard, we specify the Android SDK (currently 25), remove the check-boxes add. actions 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 be substituted later, after the inclusion of the Android Framework. SBT project is ready.

Plugin for SBT and Android integration


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

  1. First of all, add the plugins.sbt file to the project folder and add a plug- in to it

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

  2. Modify build.sbt by adding the sbt-android plug-in and task to run in the build procedure

     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 the folder structure, you should put it on one level with the Source root folder, i.e. in src/main . After creating the file, Idea / Studio will prompt us to include the Android Framework in the project. We accept the offer. Minimum manifest filling:

     <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.example"> <uses-sdk android:minSdkVersion="10" android:targetSdkVersion="25" /> <application android:label="my_app"> <activity android:name="MyActivity" android:label="MyActivityLabel"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> </application> </manifest> 

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

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

  5. Open and enable the Android emulator
  6. Refresh the project to activate all the new settings. If you are working in IDEA, then this action automatically turns on ProGuard (which we'll talk about later). 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 - Scala's adaptation to the Android platform


At the moment we have working the simplest application. If we start expanding it, for example, at least we will add the build.sbt library to build.sbt (which we'll talk about later)

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

then we run into a problem. Android platform has a limit on the number of references - 64K. Due to the features of the Scala code, this limit is reached quickly. And by simply 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.

The standard approach to solving this problem:

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

As a rule, if the problem can be solved only by the first step, then only it is used. And MultiDexing is already going on if the first is not enough. For this task, ProGuard will be sufficient.
The tool is enabled in the Android Facet options: [Project Structure → Facets → Android → Proguard → Run proguard ...] . Note that the default text file with basic settings is already specified: Studio includes a file from the SDK .../Android/sdk/tools/proguard/proguard-android.txt , The 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 byte-code of Scala and Scaloid libraries, ProGuard will wipe Warnings, which in our case do not affect the result, but block the further launch process. Therefore, the option -dontwarn we remove them. Also, you need to specify that ProGuard does not cut out our handwritten code. This provides the option -keep class .

When starting, I encountered two errors:

  1. Unsupported class version number [52.0] (maximum 51.0, Java 1.7) . The reason is that the Android SDK relies 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 is a bug of the platform itself, and is solved by manual or scripted lining of the proguard-android.txt file from the Android SDK to the same cache, and then renamed 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.sbt file.

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

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

Source: https://habr.com/ru/post/327782/


All Articles