Who are you?
def speaker = new SZJUG.Speaker(
name: 'Alexey Zhokhov',
employer: 'Scentbird',
occupation: 'Grails Developer',
github: 'donbeave',
email: 'alexey@zhokhov.com',
site: 'http://www.zhokhov.com',
description: """whole-stack engineer
(back-end, front-end, mobile, UI/UX)"""
)
Android on Gradle
Groovy is inside the Gradle
You probably know Groovy through Gradle already.
Groovy is a superset of Java.
It contains lots of cool stuff that makes Java fun!
So,
Why can Groovy be
Android' Swift?
Android N supports Java 8
"Android is in the Java stone age state"
But not released
Multi-faceted language:
Object-oriented
Dynamic
Functional
Static
Groovy is
Straightforward integration with Java.
Java on Android is very verbose
public class FeedActivity {
TextView mTextView;
void updateFeed() {
new FeedTask().execute("http://path/to/feed");
}
class FeedTask extends AsyncTask<String, Void, String> {
protected String doInBackground(String... params) {
DefaultHttpClient httpclient = new DefaultHttpClient(new BasicHttpParams());
HttpPost httppost = new HttpPost(params[0]);
InputStream inputStream = null;
String result = null;
1/4
try {
HttpResponse response = httpclient.execute(httppost);
HttpEntity entity = response.getEntity();
inputStream = entity.getContent();
// json is UTF-8 by default
BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream, "UTF-8"), 8);
StringBuilder sb = new StringBuilder();
String line = null;
while ((line = reader.readLine()) != null) {
sb.append(line).append("n");
}
result = sb.toString();
} catch (Exception e) {
// Oops
2/4
} finally {
try {
if (inputStream != null) {
inputStream.close();
}
} catch (Exception squish) {
}
}
StringBuilder speakers = null;
try {
JSONObject jObject = new JSONObject(result);
JSONArray jArray = jObject.getJSONArray("speakers");
speakers = new StringBuilder();
for (int i = 0; i < jArray.length(); i++) {
speakers.append(jArray.getString(i));
speakers.append(" ");
}
3/4
} catch (JSONException e) {
// do something?
}
return speakers.toString();
}
@Override
protected void onPostExecute(String s) {
mTextView.setText(s);
}
}
}
4/4
So now,
let’s see the equivalent in Groovy
(no kidding either)
class FeedActivity {
TextView mTextView
void updateFeed() {
Fluent.async {
def json = new JsonSlurper().parse([:], new URL('http://path/to/feed'), 'utf-8')
json.speakers.join(' ')
} then {
mTextView.text = it
}
}
}
Because I'm lazy, I don't like to write a lot of code.
And Groovy helps me with that.
It's not only for writing less code,
it's also for cool features and good readability.
very consice language, actually
Semicolons
Parenthesis
return keyword
public keyword
Optional
Sugar syntax
1) Groovy truth
// if (s != null && s.length() > 0) { ...}
if (s) { ... }
// easy check for empty maps, list, empty strings
2) Elvis
def name = person.name ?: "unknown"
3) Save navigation
order?.lineItem?.item?.name
Where I have seen it?
Right, Apple's Swift
language was inspired by Groovy
4) List, maps (Groovy)
def shoppingList = ["catfish", "water", "tulips", "blue paint"]
shoppingList[1] = "bottle of water"
def occupations = [
"Malcolm": "Captain",
"Kaylee": "Mechanic",
]
occupations["Jayne"] = "Public Relations"
def emptyMap = [:]
def emptyList = []
4) List, maps (Swift)
var shoppingList = ["catfish", "water", "tulips", "blue paint"]
shoppingList[1] = "bottle of water"
var occupations = [
"Malcolm": "Captain",
"Kaylee": "Mechanic",
]
occupations["Jayne"] = "Public Relations"
var emptyMap = [:]
var emptyList = []
5) Named parameters (Groovy)
def triangleAndSquare =
new TriangleAndSquare(size: 10, name: "another test shape")
5) Named parameters (Swift)
var triangleAndSquare =
TriangleAndSquare(size: 10, name: "another test shape")
6) @Lazy annotation (Groovy)
class DataManager {
@Lazy importer = new DataImporter()
}
6) @Lazy annotation (Swift)
class DataManager {
@lazy var importer = DataImporter()
}
7) Closure (Groovy)
numbers.collect { int number ->
def result = 3 * numbers
return result
}
7) Closure (Swift)
numbers.map({
(number: Int) -> Int in
let result = 3 * number
return result
})
What else is cool in Groovy?
8) Builders import groovy.json.*
def json = new JsonBuilder()
json.conference {
name 'SZJUG'
subject 'Groovy on Android'
date 2016
time ['13:00', '16:00']
address {
place 'GRAPE 联合创业空间'
street '布吉街道吉华路247号下水径商业大厦三层 3/f'
district '龙岗区'
city '深圳市'
country '中国'
}
}
{
"conference": {
"name": "SZJUG",
"subject": "Groovy on Android",
"date": 2016,
"time": [
"13:00",
"16:00"
],
"address": {
"place": "GRAPE 联合创业空间",
"street": "布吉街道吉华路247号下水径商业大厦三层 3/f'",
"district": "龙岗区",
"city": "深圳市",
"country": "中国"
}
}
}
JSON
7) Immutability
@Immutable(copyWith = true)
class User {
String username, email
}
7) Immutability
// Create immutable instance of User.
def paul = new User('PaulVI', 'paul.verest@live.com')
// will throw an exception on
// paul.email = 'pupkin@mail.com'
def tomasz = mrhaki.copyWith(username: 'Tomasz')
8) String interpolation
def level = "badly"
println "I love SZJUG $level"
// Java
TextView view =
new TextView(context);
view.setText(name);
view.setTextSize(16f);
view.setTextColor(Color.WHITE);
TextView view =
new TextView(context)
view.with {
text = name
textSize = 16f
textColor = Color.WHITE
}
->
How to read text file from SD card?
def f = new FIle("/sdcard/dir/f.txt")
if (f.exists() && f.canRead()) {
view.text = f.text
}
You have to write a lot of anonymous classes EVERYWHERE
// Java
button.setOnClickListener(new View.OnClickListener() {
@Override
void onClick(View v) {
startActivity(intent);
}
})
button.onClickListener = { startActivity(intent) }
->
No native support for generating classes
at runtime
Focus on @CompileStatic
Problems
Generate bytecode, that runs
at the same speed as java files
How to start?
Gradle plugin
buildscript {
dependencies {
classpath 'com.android.tools.build:gradle:1.5.0'
classpath 'org.codehaus.groovy:gradle-groovy-android-plugin:0.3.10'
}
}
apply plugin: 'groovyx.grooid.groovy-android'
dependencies {
compile 'org.codehaus.groovy:groovy:2.4.6:grooid'
}
Performance
Groovy jar 4.5 MB
Application size 2 MB
ProGuard only 1 MB!
~8.2 MB of RAM
for @CompileStatic
if not - slower and more RAM
Frameworks
SwissKnife
http://arasthel.github.io/SwissKnife/
def "should display hello text"() {
given:
def textView = new TextView(RuntimeEnvironment.application)
expect:
textView.text == "Hello"
}
Familiar with that?
Spock
http://robospock.org/
?

Groovy on Android

  • 2.
  • 3.
    def speaker =new SZJUG.Speaker( name: 'Alexey Zhokhov', employer: 'Scentbird', occupation: 'Grails Developer', github: 'donbeave', email: 'alexey@zhokhov.com', site: 'http://www.zhokhov.com', description: """whole-stack engineer (back-end, front-end, mobile, UI/UX)""" )
  • 4.
  • 5.
    Groovy is insidethe Gradle You probably know Groovy through Gradle already. Groovy is a superset of Java. It contains lots of cool stuff that makes Java fun!
  • 6.
    So, Why can Groovybe Android' Swift?
  • 7.
    Android N supportsJava 8 "Android is in the Java stone age state" But not released
  • 8.
  • 9.
    Java on Androidis very verbose
  • 10.
    public class FeedActivity{ TextView mTextView; void updateFeed() { new FeedTask().execute("http://path/to/feed"); } class FeedTask extends AsyncTask<String, Void, String> { protected String doInBackground(String... params) { DefaultHttpClient httpclient = new DefaultHttpClient(new BasicHttpParams()); HttpPost httppost = new HttpPost(params[0]); InputStream inputStream = null; String result = null; 1/4
  • 11.
    try { HttpResponse response= httpclient.execute(httppost); HttpEntity entity = response.getEntity(); inputStream = entity.getContent(); // json is UTF-8 by default BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream, "UTF-8"), 8); StringBuilder sb = new StringBuilder(); String line = null; while ((line = reader.readLine()) != null) { sb.append(line).append("n"); } result = sb.toString(); } catch (Exception e) { // Oops 2/4
  • 12.
    } finally { try{ if (inputStream != null) { inputStream.close(); } } catch (Exception squish) { } } StringBuilder speakers = null; try { JSONObject jObject = new JSONObject(result); JSONArray jArray = jObject.getJSONArray("speakers"); speakers = new StringBuilder(); for (int i = 0; i < jArray.length(); i++) { speakers.append(jArray.getString(i)); speakers.append(" "); } 3/4
  • 13.
    } catch (JSONExceptione) { // do something? } return speakers.toString(); } @Override protected void onPostExecute(String s) { mTextView.setText(s); } } } 4/4
  • 14.
    So now, let’s seethe equivalent in Groovy (no kidding either)
  • 15.
    class FeedActivity { TextViewmTextView void updateFeed() { Fluent.async { def json = new JsonSlurper().parse([:], new URL('http://path/to/feed'), 'utf-8') json.speakers.join(' ') } then { mTextView.text = it } } }
  • 16.
    Because I'm lazy,I don't like to write a lot of code. And Groovy helps me with that.
  • 17.
    It's not onlyfor writing less code, it's also for cool features and good readability. very consice language, actually
  • 18.
  • 19.
  • 20.
    1) Groovy truth //if (s != null && s.length() > 0) { ...} if (s) { ... } // easy check for empty maps, list, empty strings
  • 21.
    2) Elvis def name= person.name ?: "unknown"
  • 22.
  • 23.
    Where I haveseen it?
  • 24.
    Right, Apple's Swift languagewas inspired by Groovy
  • 25.
    4) List, maps(Groovy) def shoppingList = ["catfish", "water", "tulips", "blue paint"] shoppingList[1] = "bottle of water" def occupations = [ "Malcolm": "Captain", "Kaylee": "Mechanic", ] occupations["Jayne"] = "Public Relations" def emptyMap = [:] def emptyList = []
  • 26.
    4) List, maps(Swift) var shoppingList = ["catfish", "water", "tulips", "blue paint"] shoppingList[1] = "bottle of water" var occupations = [ "Malcolm": "Captain", "Kaylee": "Mechanic", ] occupations["Jayne"] = "Public Relations" var emptyMap = [:] var emptyList = []
  • 27.
    5) Named parameters(Groovy) def triangleAndSquare = new TriangleAndSquare(size: 10, name: "another test shape")
  • 28.
    5) Named parameters(Swift) var triangleAndSquare = TriangleAndSquare(size: 10, name: "another test shape")
  • 29.
    6) @Lazy annotation(Groovy) class DataManager { @Lazy importer = new DataImporter() }
  • 30.
    6) @Lazy annotation(Swift) class DataManager { @lazy var importer = DataImporter() }
  • 31.
    7) Closure (Groovy) numbers.collect{ int number -> def result = 3 * numbers return result }
  • 32.
    7) Closure (Swift) numbers.map({ (number:Int) -> Int in let result = 3 * number return result })
  • 33.
    What else iscool in Groovy?
  • 34.
    8) Builders importgroovy.json.* def json = new JsonBuilder() json.conference { name 'SZJUG' subject 'Groovy on Android' date 2016 time ['13:00', '16:00'] address { place 'GRAPE 联合创业空间' street '布吉街道吉华路247号下水径商业大厦三层 3/f' district '龙岗区' city '深圳市' country '中国' } }
  • 35.
    { "conference": { "name": "SZJUG", "subject":"Groovy on Android", "date": 2016, "time": [ "13:00", "16:00" ], "address": { "place": "GRAPE 联合创业空间", "street": "布吉街道吉华路247号下水径商业大厦三层 3/f'", "district": "龙岗区", "city": "深圳市", "country": "中国" } } } JSON
  • 36.
    7) Immutability @Immutable(copyWith =true) class User { String username, email }
  • 37.
    7) Immutability // Createimmutable instance of User. def paul = new User('PaulVI', 'paul.verest@live.com') // will throw an exception on // paul.email = 'pupkin@mail.com' def tomasz = mrhaki.copyWith(username: 'Tomasz')
  • 38.
    8) String interpolation deflevel = "badly" println "I love SZJUG $level"
  • 39.
    // Java TextView view= new TextView(context); view.setText(name); view.setTextSize(16f); view.setTextColor(Color.WHITE); TextView view = new TextView(context) view.with { text = name textSize = 16f textColor = Color.WHITE } ->
  • 40.
    How to readtext file from SD card? def f = new FIle("/sdcard/dir/f.txt") if (f.exists() && f.canRead()) { view.text = f.text }
  • 41.
    You have towrite a lot of anonymous classes EVERYWHERE // Java button.setOnClickListener(new View.OnClickListener() { @Override void onClick(View v) { startActivity(intent); } }) button.onClickListener = { startActivity(intent) } ->
  • 42.
    No native supportfor generating classes at runtime Focus on @CompileStatic Problems Generate bytecode, that runs at the same speed as java files
  • 43.
  • 44.
    Gradle plugin buildscript { dependencies{ classpath 'com.android.tools.build:gradle:1.5.0' classpath 'org.codehaus.groovy:gradle-groovy-android-plugin:0.3.10' } } apply plugin: 'groovyx.grooid.groovy-android' dependencies { compile 'org.codehaus.groovy:groovy:2.4.6:grooid' }
  • 45.
  • 46.
    Groovy jar 4.5MB Application size 2 MB ProGuard only 1 MB! ~8.2 MB of RAM for @CompileStatic if not - slower and more RAM
  • 47.
  • 48.
  • 49.
    def "should displayhello text"() { given: def textView = new TextView(RuntimeEnvironment.application) expect: textView.text == "Hello" } Familiar with that?
  • 50.
  • 51.