On Github pieces029 / GDG-DevFest-2015
A multi-faceted language for the Java platform
Groovy is a powerful, optionally typed and dynamic language, with static-typing and static compilation capabilities, for the Java platform aimed at multiplying developers’ productivity thanks to a concise, familiar and easy to learn syntax. It integrates smoothly with any Java program, and immediately delivers to your application powerful features, including scripting capabilities, Domain-Specific Language authoring, runtime and compile-time meta-programming and functional programming.
Java
List<StringList<String> names = new ArrayList<String>(); names.add("Mike"); names.add("Dave"); names.add("Steve"); for (String name : names) { System.out.println(name); }
Groovyfy It!
List<StringList<String> names = new ArrayList<String>() names.add("Mike") names.add("Dave") names.add("Steve") for (String name : names) { println name }- Remove ; - Don't need () - println
More Groovy!
def names = ["Mike", "Dave", "Steve"] names.each { println it }- Better list creation - Optional Type def - Each / Awesome Collections API
Java Model
public final class Person { private final String firstName; private final String lastName; public Person(String firstName, String lastName) { this.firstName = firstName; this.lastName = lastName; } public String getFirstName() { return firstName; } public String getLastName() { return lastName; } @Override public boolean equals(Object o) { /*lots of code here*/ } @Override public int hashCode() { /*lots of code here*/ } @Override public String toString() { /*lots of code here*/ } }
Groovy Model
@Immutable final class Person { private final String firstName private final String lastName } def person1 = new Person("Leslie", "Knope") def person2 = new Person(firstName: "Ben", lastName: "Wyatt") // Named constructors!Groovy constructors are pretty sweet!
Java: Android Button Press
button.setOnClickListener(new View.OnClickListener() { @Override void onClick(View v) { //... } });
Groovy: Android Button Press
button.onClickListener = { //... }
Java File Read
int len; char[] chr = new char[4096]; final StringBuffer buffer = new StringBuffer(); final FileReader reader = new FileReader(new File("/path/to/file")); try { while ((len = reader.read(chr)) > 0) { buffer.append(chr, 0, len); } } finally { reader.close(); } System.out.println(buffer.toString());Have to look it up every time. Commons-IO helps, but not enough Missing try catch around close (auto close in java 7 but not supported in Android)
Groovy File Read
println new File("/path/to/file").textSame can be done with Network Calls new URL("http://google.com").text
Other awesome things
Java -> Compiled Java sources -> .class files -> Dex -> classes.dex -> APK File -> Runtime
Groovy -> Compiled Groovy sources -> .class files -> Dex -> classes.dex -> APK File -> Runtime
Problems
Add the plugin to gradle
buildscript { repositories { jcenter() } dependencies { classpath 'com.android.tools.build:gradle:1.0.0' classpath 'org.codehaus.groovy:gradle-groovy-android-plugin:0.3.5' } }1.1.+ support with 0.3.6
dependencies { compile 'org.codehaus.groovy:groovy:2.4.1:grooid' }
https://github.com/Arasthel/SwissKnife
class MyActivity extends Activity { @SaveInstance public String myString; @OnClick(R.id.button) void onButtonClicked(Button button) { Toast.makeText(this, "Button clicked", Toast.LENGTH_SHOT).show(); } @OnBackground void doSomeProcessing(URL url) { // Contents will be executed on background } @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); // This must be called for injection of views and callbacks to take place SwissKnife.inject(this); // This must be called for saved state restoring SwissKnife.restoreState(this, savedInstanceState); } }
public final class Person implements Parcelable { private final int id private final String firstName private final String lastName public void writeToParcel(Parcel out, int flags) { out.writeInt(id); out.writeString(firstName); out.writeString(lastName); } public static final Parcelable.Creator<Person> CREATOR = new Parcelable.Creator<Person>() { public Person createFromParcel(Parcel in) { return new Person(in); } public Person[] newArray(int size) { return new Person[size]; } }; private Person(Parcel in) { id = in.readInt(); firstName = in.readString(); lastName = in.readString(); } public getId() { return id; } public getFirstName { return firstName; } public getLastName { return lastName; } }
@Parcelable class Person { int id String firstName String lastName }
https://github.com/pieces029/android-spock
class MainActivitySpec extends Specification { @UseActivity(MainActivity) def activity def "test activity setup"() { expect: activity != null activity instanceof MainActivity } def "test layout"() { given: def button = activity.findViewById(R.id.main_button) as Button when: def buttonText = button.getText() then: buttonText == "Test" } }
Circle Stacker
Groovy doesn't fix the problems android has, but it's a great tool to smooth them over.