scala on-android
DESCRIPTION
Scala on Android: My ExperienceTRANSCRIPT
Scala on Android
Android Development
● Write lots of Java code● Write UI and other resources in XML● Generate Java code from resources● Compile Java code into “.class” files● Run proguard● Compile class files to Dalvik Executable (DEX)● Deploy on device
Dalvik VM
● Does not support “.class” bytecode format● Can not use libraries which generate bytecode● Devices have limited CPU and Memory● Can not easily share libraries between
applications
Eclipse
● Has nice UI editors● IDE is a build tool
Alternative Languages for Android
Jython
● Does not have enough community support● Slow● Dynamic
JRuby
● Ruboto framework● Dynamic● Need to use java code generation
Clojure
● Very cool :)● Very slow start-up time● Sometimes need to generate bytecode
PHP
Who cares?
Rhino
● Nice language● Can run with optimization turned off● Completely interpreted● Dynamic
Groovy
???
Scala
● Statically typed● Compiled to Java bytecode● Has access to all classes in Android● Fast
● but sometimes slow :)
● Has SBT● Android● Maven artifacts
How to build Scala apps for Android
● ANT● Maven● SBT + Android Plugin
Little nice things about Scala
Type Inference
● Improve readability● Reduce number of imports● Less typing
val stream = getAssets().open("areas.json")
val stream: InputStream = getAssets().open("areas.json")
Import statement
import android.view.{
Window, Menu, MenuItem, KeyEvent, View
}
import android.util.Log.{e => error}
Lazy vals
lazy val searchBox =
findViewById(R.id.searchBox)
.asInstanceOf[AutoCompleteTextView]
Mixin Inheritance
class MainActivity extends MapActivity
with Logging
with DatabaseHelpers
with MapHelpers
Collections
● Best collection library I ever used● Sorry google-collections...
● Using arrays is easy● @specialized
Collection examples
val suggestions = areas map { _.name }
val index = areas.indexWhere(
_.name == searchString
)
val index =
areas.indexWhere(_.contains(coordinate))
pointList.minBy(_.lat)
First class functions
class AreaOverlay(
areas: Array[Area],
selectListener: Int => Unit
)
new AreaOverlay(
areas, this.onAreaSelected
)
Convert listeners into functions
implicit def fn2ClickListener(
f: View => Unit
): View.OnClickListener =
new View.OnClickListener() {
override def onClick(v: View) = f(view)
}
exitButton.setOnClickListener(
this.onExitClick
)
Files
● Directory structure is not forced to mirror packages
● Files can contain any amount of classes
Pattern matching
● No NPEs when using Option[T]● Easy to work with data objects
Pattern matching
lastLocation match {
case Some(c@Coordinate(lat, lon)) =>
...
case None =>
...
}
Implicits
implicit def coordinate2geopoint(
c: Coordinate
): GeoPoint = new GeoPoint(
c.lat * 1.0e6 toInt, c.lon * 1.0e6 toInt
)
XML
for (s <- xml \ "Document" \ "Style")
placemarkElem \ "Polygon" \
"outerBoundaryIs" \ "LinearRing" \
"coordinates"
Bad stuff
● Performance sensitive parts● Learn to use “javap”● Remove for-comprehensions and lambda functions● Do not use boxed types “by accident”
● Tools● UI Editor● Debugger● Build time (dex'ing of scala library)
What I missed from Java
● Google Guice● Maven● Good Eclipse integration● Feeling important...
Thank you!
Questions?