Groovy et Android : le couple gagnant

Groovy et Android : le couple gagnant

Talk donné à SoftShake 2014 #groovylang #android

F929f5d80ef8a23b67ad8ac6f08416cd?s=128

Cédric Champeau

October 24, 2014
Tweet

Transcript

  1. © 2014 SpringOne 2GX. All rights reserved. Do not distribute

    without permission. Groovy and Android, a winning pair? By Cédric Champeau Groovy et Android : le couple gagnant @CedricChampeau
  2. #softshake #groovylang #android @CedricChampeau About me Pivotal employee Core Groovy

    committer Compilation configuration Static type checking & Static compilation Traits, new template engine, ... Groovy in Action 2 co-author Misc OSS contribs (Gradle plugins, deck2pdf, jlangdetect, ...) 2
  3. 5

  4. #softshake #groovylang #android @CedricChampeau Why Android? • Uses a JVM

    • SDK is free • Tooling also freely available (Android Studio) • Swift anyone? 6
  5. #softshake #groovylang #android @CedricChampeau Why Groovy? • Built on top

    of the shoulders of a Giant (Java) • Runs a JVM • Android developers shouldn't be suffering • Java on Android is very verbose • And the main development language on the platform • Multi-faceted language • OO, Imperative, functional, scripting, dynamic, static, … • Straightforward integration with Java 7
  6. #softshake #groovylang #android @CedricChampeau Why Groovy? button.setOnClickListener(new View.OnClickListener() { @Override

    void onClick(View v) { startActivity(intent); } }) 8 button.onClickListener = { startActivity(intent) }
  7. #softshake #groovylang #android @CedricChampeau Why Groovy? @RestableEntity @ToString class User

    { String name String phone String avatar Integer balance static constraints = { name pattern: ~/[a-zA-Z]+/, min: 3, max: 5, blank: false, nullable: false phone pattern: ~/\d+/, size: 2..4 balance range: 10..100 } } 9 Groovy Beans Grails-like entities
  8. #softshake #groovylang #android @CedricChampeau Why Groovy? def user = new

    User(name: 'Name') form(R.id.user_form, user) { form -> editText(R.id.user_name).attach('name') editText(R.id.user_phone).attach('phone') editText(R.id.user_balance).attach('balance') form.submit(R.id.submit_button) { if (form.object.validate()) { this.showToast('Validated with success!') } else { form.object.errors.each { this.showToast(it.toString()) } } } } 10 declarative code
  9. #softshake #groovylang #android @CedricChampeau Groovy on Android: the problems •

    Groovy is a dynamic language • Not everything done at compile time • Intensive use of reflection • Potentially slow invocation pathes • Battery? • Bytecode is different • Classes at runtime? 11
  10. #softshake #groovylang #android @CedricChampeau Groovy on Android: the problems •

    Not all classes are available • java.bean.xxx very problematic • Multiple runtimes • Dalvik • ART • Behavior not the same as the standard JVM 12
  11. #softshake #groovylang #android @CedricChampeau Groovy on Android: discobot • Early

    days • Written in 2011 • Fork of Groovy 1.7 • Capable of running scripts at runtime • but slow... 13
  12. #softshake #groovylang #android @CedricChampeau Groovy on Android: dex files •

    Dalvik VM = alternative bytecode • Groovy generates JVM bytecode • Translation done through dex • No native support for generating classes at runtime 14
  13. #softshake #groovylang #android @CedricChampeau Compiling an Android application • Classic

    process 15
  14. #softshake #groovylang #android @CedricChampeau Compiling an Android application • Classic

    process for a Groovy application 16
  15. #softshake #groovylang #android @CedricChampeau Discobot process • Write Groovy bytes

    to a file • Package those into a jar • Use a special classloader to load the class • Enjoy! 17
  16. #softshake #groovylang #android @CedricChampeau Compiling an Android application • Runtime

    generation of classes 18
  17. #softshake #groovylang #android @CedricChampeau Discobot process • Works, but very

    slow • Lots of I/O involved • What about ASMDex? • Same approach used by Ruboto • Nice proof of concept 19
  18. #softshake #groovylang #android @CedricChampeau Redefinining objectives

  19. #softshake #groovylang #android @CedricChampeau Groovy 2.4: Objectives for Android •

    Supporting Android in the standard distribution • Building a full Android application in Groovy • Main focus on @CompileStatic • Optional use of dynamic Groovy 21
  20. #softshake #groovylang #android @CedricChampeau Groovy 2.4: Objectives for community •

    Community is a major strenght of Groovy • We need you for Android too! • Bring the goodness of Groovy to Android • Invent new frameworks! 22
  21. #softshake #groovylang #android @CedricChampeau Groovy for Android

  22. #softshake #groovylang #android @CedricChampeau It already works! 24

  23. #softshake #groovylang #android @CedricChampeau Requirements • Gradle • Android Studio

    • Or your favorite editor... • Groovy 2.4.0-beta-3 • A good tutorial on Android... 25
  24. #softshake #groovylang #android @CedricChampeau Groovy 2.4 Android Support • Must

    use a specific Android jar • Use of the grooid classifier • Replaces java.beans use with openbeans • Workarounds for Android specific behavior • Reduced number of methods in bytecode • Important for the 64k limit of dex files 26
  25. #softshake #groovylang #android @CedricChampeau Gradle plugin • Gradle is the

    new default build system for Android • apply plugin: 'com.android.application' • Uses a non standard compilation process • Without Groovy specific plugin, lots of trickery involved • Thus apply plugin: apply plugin: 'me.champeau.gradle.groovy- android' • Supports both the application and library plugins 27
  26. #softshake #groovylang #android @CedricChampeau Gradle plugin buildscript { repositories {

    jcenter() } dependencies { classpath 'com.android.tools.build:gradle:0.12.2' classpath 'me.champeau.gradle:gradle-groovy-android-plugin:0.3.0' } } apply plugin: 'me.champeau.gradle.groovy-android' dependencies { compile 'org.codehaus.groovy:groovy:2.4.0-beta-3:grooid' } 28
  27. #softshake #groovylang #android @CedricChampeau Then code! @CompileStatic @ToString(includeNames = true)

    @EqualsAndHashCode class Session { Long id Long speakerId Slot slot String title String summary List<String> tags } 29
  28. #softshake #groovylang #android @CedricChampeau Groovifying Android APIs 31 class FeedTask

    extends AsyncTask<String, Void, String> { protected String doInBackground(String... params) { // very long boilerplate code.... } @Override protected void onPostExecute(String s) { mTextView.setText(s); } }
  29. #softshake #groovylang #android @CedricChampeau Groovifying Android APIs 32 Fluent.async {

    def json = new JsonSlurper().parse([:], new URL('http://path/to/feed'), 'utf-8') json.speakers.join(' ') } then { mTextView.setText(it) }
  30. #softshake #groovylang #android @CedricChampeau Performance?

  31. #softshake #groovylang #android @CedricChampeau System resources • Example of the

    GR8Conf Agenda application • Groovy jar: 4.5MB • Application size: 2MB! • After ProGuard: only 1MB! • ~8.2MB of RAM! (but lots of images) 34
  32. #softshake #groovylang #android @CedricChampeau Community

  33. #softshake #groovylang #android @CedricChampeau Community projects • Community is more

    important than the language • New frameworks to invent • Some already did! 36
  34. #softshake #groovylang #android @CedricChampeau SwissKnife • Similar to Android Annotations

    and ButterKnife • Based on AST transformations • View injection • Threading model • Works with annotations to generate code 37
  35. #softshake #groovylang #android @CedricChampeau SwissKnife 38 class MyActivity extends Activity

    { @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) } }
  36. #softshake #groovylang #android @CedricChampeau Grooid Tools 39 View view =

    new AndroidBuilder().build(this) { relativeLayout(width: MATCH_PARENT, height: MATCH_PARENT, padding: [dp(64), dp(16)]) { textView(width: MATCH_PARENT, height: dp(20), text: R.string.hello_world) } } • Builders for views • Experimental • https://github.com/karfunkel/grooid-tools
  37. #softshake #groovylang #android @CedricChampeau Potential issues 40 • Performance of

    dynamic Groovy on low end-devices • Use @CompileStatic whenever possible • The infamous 64k method count • Use ProGuard! • Tooling support • Groovy not fully supported by Android Studio • Google support • Android Gradle plugin updates are very frequent
  38. #softshake #groovylang #android @CedricChampeau “Best of all, I expect to

    try to update Android Studio right before the talk, so I have the latest possible version in the so­called Canary channel. What could possibly go wrong?” Ken Kousen, September 10th, 2014
  39. #softshake #groovylang #android @CedricChampeau Other ideas 42 • Dagger-like dependency

    injection framework? • Data binding APIs • Improved reactive APIs • You can already use Reactor or RxJava
  40. #softshake #groovylang #android @CedricChampeau Future is now! 43 • New

    York Times next app will be written in Groovy!
  41. 44 @CedricChampeau melix http://melix.github.io/blog