Top Banner
android.talks@infinum.hr
42

Infinum android talks_10_getting groovy on android

Jul 18, 2015

Download

Software

Infinum Ltd.
Welcome message from author
This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
Transcript
Page 2: Infinum android talks_10_getting groovy on android

Getting

on AndroidIvan Kušt

Page 3: Infinum android talks_10_getting groovy on android

Java on Android

• no Java 8 and lambda expressions

• writing a lot of boilerplate code

Page 4: Infinum android talks_10_getting groovy on android
Page 5: Infinum android talks_10_getting groovy on android

Groovy

• optionally typed

• dynamic language

• compiles into Java VM bytecode

Page 6: Infinum android talks_10_getting groovy on android

Groovy

Thread thread = new Thread(new Runnable() { @Override void run() { //do stuff in background } });

• example (executing code in a new thread) on Java:

Page 7: Infinum android talks_10_getting groovy on android

Groovy

• same thing in Groovy, using closures:

Thread.start { //do stuff in background }

Page 8: Infinum android talks_10_getting groovy on android

Groovy

• more concise code

• more readable code

• still type safe

• still fast

Page 9: Infinum android talks_10_getting groovy on android

Benefits of Groovy• semi colons are optional

• parentheses are optional

• dynamic typing

• return keyword is optional

• public keyword is optional

• all Java is valid Groovy

Page 10: Infinum android talks_10_getting groovy on android

vs

Page 11: Infinum android talks_10_getting groovy on android

Default imports• java.io.*

• java.lang.*

• java.math.BigDecimal

• java.math.BigInteger

• java.net.*

• java.util.*

• groovy.lang.*

• groovy.util.*

Page 12: Infinum android talks_10_getting groovy on android

Special operators

• Elvis operator

• ?. operator

def name = person.name ?: "unknown"

def name = person?.name

Page 13: Infinum android talks_10_getting groovy on android

Initializers• Java:

• Groovy:

int[] array = { 1, 2, 3}

int[] array = [1,2,3]

• { … } block reserved for closures

Page 14: Infinum android talks_10_getting groovy on android

Initializers

def list = [1, 2, 3, 4 ,5] def map = [a: 1, b: 2, c:3] def regex = ~/.*foo.*/def range = 128..255def closure = {a, b -> a + b}

• other available initializers:

Page 15: Infinum android talks_10_getting groovy on android

== operator

• == in groovy translates to: a.compareTo(b) == 0 if they are Comparable a.equals(b) otherwise

Page 16: Infinum android talks_10_getting groovy on android

Groovy truth

• in Java:

• in Groovy:if(s)

if(s != null && s.length() > 0)

Page 17: Infinum android talks_10_getting groovy on android

Package scope

• Java: package private field

• Groovy: property

• package private field in groovy:

class Person { String name}

class Person { @PackageScope String name}

Page 18: Infinum android talks_10_getting groovy on android

Multi-methods

• java: result = 2 (method chosen at compile time)

• groovy: result = 1 (method chosen at run time)

int method(String arg) { return 1;}int method(Object arg) { return 2;}

Object o = "Object";int result = method(o);

Page 19: Infinum android talks_10_getting groovy on android

Properties

public class Pokemon { private String name; public String getName() { return name; } public void setName(String name) { this.name = name; }}

Pokemon pokemon = new Pokemon();pokemon.setName("Pikachu");

public class Pokemon { String name; }

Pokemon pokemon = new Pokemon(name: "Pikachu") pokemon.setName("Raichu")

Page 20: Infinum android talks_10_getting groovy on android

Annotation processing

• no annotation processing in Groovy

• AST transformations

• example: @Immutable - implements immutable “by the book”

Page 21: Infinum android talks_10_getting groovy on android

AST transformations example

public final class Person { private final String name; private final int age; public Person(String name, int age) { this.name = name; this.age = age; } public String getName() { return name; } public int getAge() { return age; } @Override public int hashCode() { return age + 31 * name.hashCode(); } @Override public boolean equals(Object other) { if(other == null) { return false; } if(this == other) { return true; } if(Person.class != other.getClass()) { return false; } Person otherPerson = (Person) other; if(!name.equals(otherPerson.name)) { return false; } if(age != otherPerson.age) { return false; } return true; } @Override public String toString() { return "Person(" + name + ", " + age + ")"; } }

import groovy.transform.Immutable@Immutablepublic class Person { String name; int age; }

Page 22: Infinum android talks_10_getting groovy on android

with {} method

view = new TextView(context);view.setName(name);view.setTextSize(16f);view.setTextColor(Color.WHITE);

view = new TextView(context); view.with { text = name textSize = 16f textColor = Color.WHITE}

Page 23: Infinum android talks_10_getting groovy on android

Resource handling

File f = new File("/sdcard/dir/f.txt");if(f.exists() && f.canRead()) { FileInputStream fis = null; try { fis = new FileInputStream(f); byte[] bytes = new byte[fis.available()]; while(fis.read(bytes) != -1) {}; textView.setText(new String(bytes)); } catch(IOException e) { //handle } finally { if(fis != null) { try { fis.close(); } catch(IOException e) { //ignore } } }} else { //handle}

def f = new File("/sdcard/dir/f.txt");if(f.exists() && f.canRead()) { f.withInputStream { fis -> def bytes = new byte[fis.available()] while(fis.read(bytes) != -1) {} textView.setText(new String(bytes)) }}

Page 24: Infinum android talks_10_getting groovy on android

HTTP GET example

def url = "https://api.github.com/repos" + "groovy/groovy-core/commits"def commits = new JsonSlurper().parseText(url.toURL().text)assert commits[0].commit.author.name == "Cedric Champeau"

• easy to parse JSON REST API:

Page 25: Infinum android talks_10_getting groovy on android

But there is more

• all the differences are described:http://groovy-lang.org/differences.html

Page 26: Infinum android talks_10_getting groovy on android

Groovy project setup

Page 27: Infinum android talks_10_getting groovy on android

Groovy project setup

Page 28: Infinum android talks_10_getting groovy on android

Groovy project setup

Page 29: Infinum android talks_10_getting groovy on android

Groovy project setup

Page 30: Infinum android talks_10_getting groovy on android

Groovy project setup

Page 31: Infinum android talks_10_getting groovy on android

Groovy project setup

Page 32: Infinum android talks_10_getting groovy on android

Modify build.gradlebuildscript { repositories { jcenter() } dependencies { classpath 'com.android.tools.build:gradle:1.0.1' classpath 'me.champeau.gradle:gradle-groovy-android-plugin:0.3.0' } } apply plugin: 'com.android.application'apply plugin: 'me.champeau.gradle.groovy-android'android { …} dependencies { compile fileTree(dir: 'libs', include: ['*.jar']) compile ‘org.codehaus.groovy:groovy-all:2.4.3' … }

Page 33: Infinum android talks_10_getting groovy on android

Add groovy code

• rename class files from .java to .groovy

• Android Studio has autocomplete support!

Page 34: Infinum android talks_10_getting groovy on android

Proguard

-dontobfuscate-keep class org.codehaus.groovy.reflection.** { *; } -keep class org.codehaus.groovy.vmplugin.** { *; } -keep class org.codehaus.groovy.runtime.dgm* { *; } -keepclassmembernames class org.codehaus.groovy.runtime.dgm* { *;} -keepclassmembernames class ** implements org.codehaus.groovy.runtime.GeneratedClosure { *;} -dontwarn org.codehaus.groovy.**-dontwarn groovy**

Page 35: Infinum android talks_10_getting groovy on android

Groovy overhead

Java Groovy

Without Proguard 947 kB 2.9 MB

With Proguard 719 kB 1.6 MB

Page 36: Infinum android talks_10_getting groovy on android

Android Groovy libraries

Page 37: Infinum android talks_10_getting groovy on android

Libraries

• all Android libraries can be used with Groovy

• caveat: annotation processing won’t be run (except for .java files)

Page 38: Infinum android talks_10_getting groovy on android

Swiss knife • Butterknife for Groovy

• same annotations as Butterknife

• in onCreate() add:

SwissKnife.inject(this);SwissKnife.restoreState(this, savedInstanceState);

compile ‘com.arasthel:swissknife:1.2.3'

• in build.gradle add:

Page 39: Infinum android talks_10_getting groovy on android

The good

• less boilerplate and more concise code

• closures

• neat Exception stacktraces for closures (vs Java 8 lambdas)

Page 40: Infinum android talks_10_getting groovy on android

The bad

• a little bit slower than Java Android project

• larger .apk

• no annotation processing (APT)

Page 41: Infinum android talks_10_getting groovy on android

Conclusion

• good for smaller projects

• faster to code

• lots of syntax sugar

• add some overhead to performance and .apk size

Page 42: Infinum android talks_10_getting groovy on android

Resources

• Groovy presentation by Guillaume Laforge: https://speakerdeck.com/glaforge/groovy-on-android-droidcon-paris-2014

• Groovy official site:http://groovy-lang.org/

• groovy project example:https://github.com/ikust/groovy-pokemons