REPL your way into Android development
by @doppioslash
12 Semptember 2015 - FunctionalKats - Dublin
So you want to make
Android apps
but not to use Java
and/or want a better way to develop Android UI
The Horror of XML
Luckily for you there are many languages you can use
Scala
Kotlin
But today we're looking at
Clojure
Interactive
Concise
(At least compared to Java. The bar is low.)
Good Interop
Watch out for
Android SDK install downloading the internet
Android
Android
Having to tap 7 times to get developer access.
(And jump counterclockwise on one foot on a full moon night)
Android
Or you can ask your cat to tap for you
Loading times
Clojure
Clojure
Solution: skummet
Still need Android proficiency
Clojure
No solution to that...
Need Android proficiency
Need Android proficiency
We can save you from XML but NOT from Android Layouts
Let me present you your new friends
[lein-droid "0.4.3"]
lein droid
A lein plugin
lein droid
Creates project
lein droid
Compiles
lein droid
Runs on device
[neko/neko "4.0.0-alpha5"]
neko
Wraps the Android API
neko
Activity
neko
Interactively develop UIs
neko
With no XML
neko
Logging
neko
Action Bars
neko
SQLite
[org.skummet/clojure "1.7.0-r1"]
skummet
Fork of Clojure
skummet
Faster boot times
skummet
More compact
skummet
Skips unused
[cider/cider-nrepl "0.9.1"]
cider
Emacs IDE and REPL
cider
M-x cider-connect
cider
cider
Will give you a REPL that runs on device
Setup
Setup
1. Create a new project with lein droid
Setup
$ lein new droid <project>
<package> <opts>
Setup
$ lein new droid anfocal
com.lambdacat.anfocal :sdk-target 23
Setup
Will automatically install the lein droid template
Setup
Tree of lein-droid app
Setup
2. Open your project.clj in Emacs
Setup
3. Specify path to Android SDK in project.clj
Setup
:sdk-path "/usr/local/opt/android-sdk"
Setup
4. Launch emulator or plug in device
Setup
(pss, the Android emulator is slow. Try Genymotion)
Setup
4. open a shell in Emacs
Setup
M-x shell
M-x shell
6. compile and launch the project
M-x shell
$ lein droid doall
M-x shell
Will compile and launch in your emulator
Setup
7. get a REPL connected with the clojure on device
Setup
M-x cider-connect
Setup
localhost:9999
M-x cider-connect
Opens REPL on device
M-x cider-connect
8. We can change the code and
C-x C-e to re-evaluate
M-x cider-connect
Setup
Demo
Android Overview
Android Overview
Activity
Activity
is a single screen
Activity
should equate to one action the user can take
Activity
eg. Login -> LoginActivity
Android Overview
Fragment
Android Overview
is a piece of UI you can use in an Activity
Android Overview
one Activity can have many Fragments
Android Overview
Intent
Android Overview
is an async message
Android Overview
that contains the data needed to do an action
Android Overview
an app/activity can offer/support an intent
Intent
eg. app: I can open a pdf
Intent
meaning it has some functionality
Intent
connects different screen in an app
Intent
but can also connect different apps
Intent
ActionBar
Intent
a way to do navigation
Intent
can show contextual buttons
neko
neko
An idiomatic wrapper to Android APIs
neko
defactivity
neko - defactivity
Is a macro
neko - defactivity
Assign unique key with :key
main.clj
You can find it again much like CSS selectors
main.clj
find-view
main.clj
main.clj
Where our main Activity resides
main.clj
... [neko.activity :refer [defactivity set-content-view!]])
(defactivity com.lambdacat.anfocal.AnFocalActivity
:key :main
(onCreate [this bundle]
(.superOnCreate this bundle)
(on-ui ...
main.clj
... (set-content-view! (*a)
[:linear-layout {:orientation :vertical}
[:edit-text {:id ::name-et
:hint "some stuff"}]
[:button {:text "Submit"}]]))))
neko - defactivity
Activity lifecycle methods (eg. onCreate)
neko - UI
set-content-view! <UI tree as a vector>
neko - UI
XML to Vectors correspondence
neko - UI
<LinearLayout
android:orientation="vertical">
<TextView
android:text="@string/hello"
android:background="#ffffff" />
</LinearLayout>
neko - UI
[:linear-layout
{:orientation :vertical}
[:text-view
{:text "Hello"
:background-color
(Color/parseColor "#ffffff")
:layout-width :fill}]]
neko - UI
<LinearLayout>
=
[:linear-layout]
neko - UI
android:orientation="vertical"
=
{:orientation :vertical}
neko - UI
This is a Neko Trait
{:orientation :vertical}
neko - UI
If a symbol is not available as a Neko Trait...
{:background-color
(Color/rgb 20 20 20)}
neko - UI
...interop will use reflection:
.setBackgroundColor ...
How to structure for REPL Development
REPL Development
Import Android classes in (:import <android.class>)
REPL Development
If you forgot to import one you can still REPL (class/method ...)
REPL Development
C-x C-e on (on-ui...) will re-evaluate the activity's UI
REPL Development
on-ui is automatically wrapped in neko.debug/safe-for-ui
REPL Development
Keep your emulator in view, errors will show up as Toasts
REPL Development
Example
I'm writing a series of articles describing making a Clojure Android app in detail on
www.lambdacat.com
Ping me at
@doppioslash
@lambda_cat
You can also get help at
#clojure-android@freenode
(thanks alexyakushev!)
REPL your way into Android development - FunctionalKats
By Claudia Doppioslash
REPL your way into Android development - FunctionalKats
- 5,818