android development with scala and sbt
TRANSCRIPT
![Page 1: Android development with Scala and SBT](https://reader035.vdocuments.site/reader035/viewer/2022062503/58ed6b9e1a28abad368b45a3/html5/thumbnails/1.jpg)
Android Development with Scala and SBT
--Anton YalyshevJetBrains
![Page 2: Android development with Scala and SBT](https://reader035.vdocuments.site/reader035/viewer/2022062503/58ed6b9e1a28abad368b45a3/html5/thumbnails/2.jpg)
AnDevCon | Contents
Contents:
1. Build tool: SBT
2. Scala for Android development
3. Simple application
4. 3rd party libraries
![Page 3: Android development with Scala and SBT](https://reader035.vdocuments.site/reader035/viewer/2022062503/58ed6b9e1a28abad368b45a3/html5/thumbnails/3.jpg)
AnDevCon | Scala Build Tool
// Project’s namename := "my-project"
version := "1.0.0"
// Add dependencieslibraryDependencies ++= Seq( "net.databinder" %% "dispatch-google" % "0.7.8", "net.databinder" %% "dispatch-meetup" % "0.7.8")
// Add dependency for testslibraryDependencies += "junit" % "junit" % "4.8" % "test"
// Define a repository by project’s version publishTo := Some(if (version.value endsWith "-SNAPSHOT") "http://example.com/maven/snapshots" else "http://example.com/maven/releases")
![Page 4: Android development with Scala and SBT](https://reader035.vdocuments.site/reader035/viewer/2022062503/58ed6b9e1a28abad368b45a3/html5/thumbnails/4.jpg)
AnDevCon | Scala Build Tool > Features
Distinctive features
● Runs in Command line
● More support in Scala ecosystem
● Convenient cross-compilation and cross-publishing
● Fast tasks execution
● Everything is a task with return value
![Page 5: Android development with Scala and SBT](https://reader035.vdocuments.site/reader035/viewer/2022062503/58ed6b9e1a28abad368b45a3/html5/thumbnails/5.jpg)
AnDevCon | Scala Build Tool Common tasks
Command Description
android:run Compile, package a debug apk and deploy it to an active device
android:packageRelease Create a signed apk
android:packageDebug Create a debug apk
test Run unit tests and report results
reload Apply changes that have been made to your sbt configuration
compile Compile the source code
clean Remove all compiled and generated code, delete ProGuard cache.
![Page 6: Android development with Scala and SBT](https://reader035.vdocuments.site/reader035/viewer/2022062503/58ed6b9e1a28abad368b45a3/html5/thumbnails/6.jpg)
AnDevCon | Scala for Android development
Benefits:● Null is replaced by Option type● Lazy values for declaration and processing● 3rd party libraries● Resolve concurrency problems
Prior information:● 65K global method limit● Tools versions compatibility
![Page 7: Android development with Scala and SBT](https://reader035.vdocuments.site/reader035/viewer/2022062503/58ed6b9e1a28abad368b45a3/html5/thumbnails/7.jpg)
AnDevCon | Scala for Android development > Option type
Option [ T ]
Some [ T ] None
case class User( firstName: String, lastName: String, phone: Option[String])
val user = User("John", "Doe", None)println("Phone: " + user.phone.getOrElse("not specified"))
![Page 8: Android development with Scala and SBT](https://reader035.vdocuments.site/reader035/viewer/2022062503/58ed6b9e1a28abad368b45a3/html5/thumbnails/8.jpg)
AnDevCon | Scala for Android development > Lazy values
Keyword Data type № of evaluations When?
val Immutable data Only once At the time of definition
Lazy val Immutable data Only once When we access it for first time
var Mutable data Only once At the time of definition
def Methods and Functions Every-time we access it When we access it
![Page 9: Android development with Scala and SBT](https://reader035.vdocuments.site/reader035/viewer/2022062503/58ed6b9e1a28abad368b45a3/html5/thumbnails/9.jpg)
AnDevCon | Scala for Android development > Lazy values
class AndroidWay extends Activity { TextView name; ImageView thumbnail;
public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); name = (TextView) findViewById(R.id.name); thumbnail = (ImageView) findViewById(R.id.thumbnail); }}
class ButterKnifeWay extends Activity { @BindView(R.id.title) TextView title; @BindView(R.id.thumbnail) ImageView thumbnail;
@Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.simple_activity); ButterKnife.bind(this); // ... }}
class ScaloidWay extends SActivity {
lazy val name = findView(TR.id.name) lazy val thumbnail = new ImageView()
onCreate { contentView = new SVerticalLayout { name.here thumbnail.here } }}
![Page 10: Android development with Scala and SBT](https://reader035.vdocuments.site/reader035/viewer/2022062503/58ed6b9e1a28abad368b45a3/html5/thumbnails/10.jpg)
AnDevCon | Scala for Android development > TR
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android">
<TextView android:id="@+id/my_title" android:layout_width="wrap_content" android:layout_height="wrap_content" />
</LinearLayout>
public class MyActivity extends Activity { @Override protected void onCreate( Bundle savedInstanceState ) { super.onCreate( savedInstanceState );
setContentView( R.layout.view );
TextView title = (TextView) findViewById( R.id.my_title ); title.setText( "Hello Java!" ); }}
class MyActivity extends Activity { override def onCreate( savedInstanceState: Bundle ) = { super.onCreate( savedInstanceState )
setContentView( R.layout.main )
val title = findViewById( R.id.my_title ).asInstanceOf[TextView] title.setText( "Hello Scala!" ) }}
class MyActivity extends Activity with TypedActivity { override def onCreate( savedInstanceState: Bundle ) = { super.onCreate( savedInstanceState )
setContentView( R.layout.main )
val title = findView( TR.my_title ) title.setText( "Hello Scala!" ) }}
![Page 11: Android development with Scala and SBT](https://reader035.vdocuments.site/reader035/viewer/2022062503/58ed6b9e1a28abad368b45a3/html5/thumbnails/11.jpg)
AnDevCon | Scala for Android development > Concurrency management
Concurrency problems are resolved by
○ Futures
○ scala-async
○ Akka. UI Fragments -> actors
○ resolvable: to fill data structure from different endpoints
![Page 12: Android development with Scala and SBT](https://reader035.vdocuments.site/reader035/viewer/2022062503/58ed6b9e1a28abad368b45a3/html5/thumbnails/12.jpg)
AnDevCon | Scala for Android > Concurrency > Futures
new AsyncTask[String, Void, String] { def doInBackground(params: Array[String]) = { doAJobTakeSomeTime(params) }
override def onPostExecute(result: String) { alert("Done!", result) }}.execute("param")
Future { val result = doAJobTakeSomeTime(params) runOnUiThread(alert("Done!", result))}
val future = async { val f1 = async { … ; true } val f2 = async { … ; 42 } if (await(f1)) await(f2) else 0}
![Page 13: Android development with Scala and SBT](https://reader035.vdocuments.site/reader035/viewer/2022062503/58ed6b9e1a28abad368b45a3/html5/thumbnails/13.jpg)
AnDevCon | Scala for Android > Concurrency > Actor model
Actor
UI Fragment 2
Actor
UI Fragment 1
Actor
UI Fragment 3
Actor
UI Fragment 4
![Page 14: Android development with Scala and SBT](https://reader035.vdocuments.site/reader035/viewer/2022062503/58ed6b9e1a28abad368b45a3/html5/thumbnails/14.jpg)
AnDevCon | Scala for Android development >
Frequent questions:
● 65K global method limit ⇒ ProGuard
● Tools versions compatibility
○ Target bytecode version: 1.7
○ Android build tools <= 23.*
![Page 15: Android development with Scala and SBT](https://reader035.vdocuments.site/reader035/viewer/2022062503/58ed6b9e1a28abad368b45a3/html5/thumbnails/15.jpg)
AnDevCon | Steps to create simple application
IDE →
![Page 16: Android development with Scala and SBT](https://reader035.vdocuments.site/reader035/viewer/2022062503/58ed6b9e1a28abad368b45a3/html5/thumbnails/16.jpg)
AnDevCon | 3rd party libraries > Scaloid > Overview
Benefits:● Easy to use● Compatible with legacy Java code● Production quality
Principles:● Simplicity; ● Programmability;● Type-safety.
![Page 17: Android development with Scala and SBT](https://reader035.vdocuments.site/reader035/viewer/2022062503/58ed6b9e1a28abad368b45a3/html5/thumbnails/17.jpg)
AnDevCon | 3rd party libraries > Scaloid > Short and easy code
val button = new Button(context)button.setText("Greet")button.setOnClickListener(new OnClickListener() { def onClick(v: View) { Toast.makeText(context, "Hello!", Toast.LENGTH_SHORT).show() }})layout.addView(button)
SButton("Greet", toast("Hello!"))
![Page 18: Android development with Scala and SBT](https://reader035.vdocuments.site/reader035/viewer/2022062503/58ed6b9e1a28abad368b45a3/html5/thumbnails/18.jpg)
AnDevCon | 3rd party libraries > Scaloid > Short and easy code
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"android:orientation="vertical" android:layout_width="match_parent"android:layout_height="wrap_content" android:padding="200dip"><TextView android:layout_width="match_parent" android:text="ID" android:id="@+id/userid"
android:layout_height="wrap_content" /><EditText android:layout_width="match_parent" android:layout_height="wrap_content"
android:id="@+id/userid" /><Button android:layout_width="match_parent" android:text="Sign in" android:id="@+id/signin"
android:layout_height="wrap_content"/></LinearLayout>
EditText userId = (EditText) findByViewId(R.id.userid);Button signin = (Button) findByViewId(R.id.signin);signin.setOnClickListener(new View.OnClickListener() { public void onClick (View v) { signin(userId.getText()) }}); new SVerticalLayout {
STextView("ID") val userId = SEditText() SButton("Sign in", signin(userId.text))}.padding(20dip)
![Page 19: Android development with Scala and SBT](https://reader035.vdocuments.site/reader035/viewer/2022062503/58ed6b9e1a28abad368b45a3/html5/thumbnails/19.jpg)
AnDevCon | 3rd party libraries > Scaloid > Short and easy code
broadcastReceiver(ConnectivityManager.CONNECTIVITY_ACTION) { doSomething()}(this, onStartStop)
Future { alert("Done!", doAJobTakeSomeTime(params))}
![Page 20: Android development with Scala and SBT](https://reader035.vdocuments.site/reader035/viewer/2022062503/58ed6b9e1a28abad368b45a3/html5/thumbnails/20.jpg)
AnDevCon | 3rd party libraries > Macroid
Macroid: motivation● XML approach limitations
● Inconvenient namespace system
● Potential risk of NPE
● Adaptation of Scala language features
![Page 21: Android development with Scala and SBT](https://reader035.vdocuments.site/reader035/viewer/2022062503/58ed6b9e1a28abad368b45a3/html5/thumbnails/21.jpg)
AnDevCon | 3rd party libraries > Macroid > Components
Button:
new Button(ctx) w[Button]
Layout:
l[LinearLayout]( w[Button] w[TextView])
Properties: w[Button] <~ text("Hello!") <~ TextTweaks.large
![Page 22: Android development with Scala and SBT](https://reader035.vdocuments.site/reader035/viewer/2022062503/58ed6b9e1a28abad368b45a3/html5/thumbnails/22.jpg)
AnDevCon | 3rd party libraries > Macroid > Tweaking
def largeText(str: String) = text (str ) + TextTweaks.large + padding (left = 8 dp)
w[Button] <~ largeText("...")
Tweaks composition ? <~ ?
ButtonList [ Button ]
Tweak [ Button ]List [ Tweak [ Button ]
Option [ Button ],...
Option [ Tweak [ Button ]Future [ Tweak [ Button ]
val caption: Future[String] = Future { ...}
myTextView <~ caption.map(text)
![Page 23: Android development with Scala and SBT](https://reader035.vdocuments.site/reader035/viewer/2022062503/58ed6b9e1a28abad368b45a3/html5/thumbnails/23.jpg)
AnDevCon | 3rd party libraries > Macroid > Snails
Fade-in Text: ”Click me!”
Snails
mybutton <~~ fadeIn(400) <~ text("Click me!") <~~ fadeOut(400)
await
val blink = fadeIn(400) ++ delay(2000) ++ fadeOut(400)
myTextView <~~ blink
await
![Page 24: Android development with Scala and SBT](https://reader035.vdocuments.site/reader035/viewer/2022062503/58ed6b9e1a28abad368b45a3/html5/thumbnails/24.jpg)
AnDevCon | 3rd party libraries > Macroid > UI Actions
val action = myTextView <~ text(“Hi!”) <~ show...action.run// orrunUi(action)
val action1 = myTextView <~ text(“Hi!”) <~ show
val action2 = myProgressBar <~ hide ...runUi(action1 ~ action2)
runUi { (myProgressBar <~~ fadeOut(400)) ~~ (myTextView <~~ blink) ~~ (myOtherVextView <~ text("Hi!"))}
![Page 25: Android development with Scala and SBT](https://reader035.vdocuments.site/reader035/viewer/2022062503/58ed6b9e1a28abad368b45a3/html5/thumbnails/25.jpg)
AnDevCon | 3rd party libraries > Macroid > Operators
Right now Await
Apply <~ <~~
Combine + ++
UI Actions seq. ~ ~~
![Page 26: Android development with Scala and SBT](https://reader035.vdocuments.site/reader035/viewer/2022062503/58ed6b9e1a28abad368b45a3/html5/thumbnails/26.jpg)
AnDevCon | 3rd party libraries > Macroid > Other features
● Scala’s implicit parameters system
● Pattern matching mechanism ● Macroid lib. Media query system
● Macroid Bricks system
● Scala types system● Contexts management● Adaptive Layout● Simple work work Fragments● Data sources adapter
![Page 27: Android development with Scala and SBT](https://reader035.vdocuments.site/reader035/viewer/2022062503/58ed6b9e1a28abad368b45a3/html5/thumbnails/27.jpg)
AnDevCon | 3rd party libraries > Macroid > Akka
Actor
UI Fragment 1
Actor
UI Fragment 1
Actor
UI Fragment 1
Actor
UI Fragment 1
libraryDependencies ++= Seq(
// this library
aar("org.macroid" %% "macroid-akka" % "2.0.0-M4"),
// akka, if not included before
"com.typesafe.akka" %% "akka-actor" % "2.3.9"
)
![Page 28: Android development with Scala and SBT](https://reader035.vdocuments.site/reader035/viewer/2022062503/58ed6b9e1a28abad368b45a3/html5/thumbnails/28.jpg)
AnDevCon | Summary
1. SBT as de-facto build tool for Scala projects
2. Scala language features help us in
- risks of NPE
- values calculation control
- concurrency problems
3. 3rd party libraries
- type-safety
- simplification in work with platform
![Page 29: Android development with Scala and SBT](https://reader035.vdocuments.site/reader035/viewer/2022062503/58ed6b9e1a28abad368b45a3/html5/thumbnails/29.jpg)
AnDevCon | Outro
Real-world Android Scala SBT projects:● Tuner & Metronome● Translate Bubble● MyCarFinder● ScalaDays official app● Bump and Flock● Android MusicPlayer● 9 Cards Home Launcher● Scala API Demos● SSH Beam● Douban Books● L Camera● ...
ProGuard: proguard.sourceforge.net Scaloid: github.com/pocorall/scaloid Macroid: macroid.github.io
Scala Plugin: https://github.com/JetBrains/intellij-scala
--Anton [email protected]