Droidcon 2015 London (Part 2)

Liudas Survila
7 min readNov 5, 2015

--

Continuing my recap of Droidcon talks!

Talks covered:

  • Gradle Plugin: Take it to the next level
  • Workshop: Android Katas
  • Keynote — Android for Java Developers

Gradle Plugin: Take it to the next level

by @eyal_lezmy

How to make a plugin (Genymotion example). Slides are available here. Full Genymotion plugin source code here. Note that actual source code is a bit different than examples in presentation, but you can still get an idea.

Gradle plugin — Gradle (Groovy project). What makes it good:

  • readable (user can easily understand, use containers and closures)
  • flexible (express complex situations in a simple way)
  • intuitive (easily configurable)
  • talkative (good documentation, documentation of gradle itself can be very misleading and outdated, best documentation = source code)

Gradle source code:

$ git clone https://android.googlesource.com/platform/tools/base
$ git checkout tags/gradle_1.3.1

Genymotion plugin usage example and hints to the plugin source code:

apply plugin: 'genymotion'// extension is created in GenymotionPlugin.class
genymotion {
// using nested extension, is created in GenymotionPlugin.class
config {
licenseServer true
licenseServerAddress “192.168.1.33”
sdkPath “/home/me/Android/sdk”
useCustomSdk true
}
// launches devices, installs apks and
// this method project.genymotion.devices(Closure c) is defined in
// GenymotionExtension.class
devices {
// using a container to define DeviceLaunches, passed from
// plugin to extension
Nexus5 {
template “Google Nexus 5–5.0.0 — API 21–1080x1920”
width 1920
height 1080
density “xxhdpi”
// array property, which defines what apk's to install to
// device, defined in DeviceLaunch.class
install [“path/to/apk”, “path/to/apk2”]
// two parameters defining to pull file 'from' and 'to'
// defined in DeviceLaunch.class
pullAfter [“/sdcard/prop.txt”:”/tmp/”,
“/sdcard/data.db”:”/tmp/”]
stopWhenFinished true
}
Nexus4 {

}
}
}

Gradle plugin contains:

class GenymotionPlugin implements Plugin<Project> {  void apply(Project project) {    def instantiator = project.gradle.services.get(Instantiator)
// Create a container for DeviceLaunch (pojo)
// Factory will build DeviceLaunches
def deviceLaunches = project.container(DeviceLaunch,
new DeviceLaunchFactory(instantiator))
// Create the extension, add the DeviceLaunch container
project.extensions.create(“genymotion”,
GenymotionExtension, project, deviceLaunches)
project.genymotion.extensions.create(‘config’, GenymotionConfig)
// tasks are injected after evaluation
project.afterEvaluate {
project.genymotion.injectTasks()
}
}
}
class GenymotionExtension {  // collection of DeviceLaunch (container)
NamedDomainObjectContainer<DeviceLaunch> deviceLaunches
// we get deviceLaunches from plugin apply() method
GenymotionExtension(Project project, deviceLaunches) {
this.project = project
this.deviceLaunches = deviceLaunches
}
// create the syntax genymotion.devices{}
// same devices method defined you put into build.gradle
def devices(Closure closure) {
// let Gradle add all the declared items
deviceLaunches.configure(closure)
}
}

Factory and model

class DeviceLaunchFactory implements  NamedDomainObjectFactory<DeviceLaunch> {   final Instantiator instantiator

public DeviceLaunchFactory(Instantiator instantiator) {
this.instantiator = instantiator
}
@Override
DeviceLaunch create(String name) {
// returns new instance of DeviceLaunch
return instantiator.newInstance(DeviceLaunch.class, name)
}
}
class DeviceLaunch { String name DeviceLaunch(String name) {
this.name = name
}

// launch, install, etc
}

Talk also covers testing of the plugin using JUnit. Check out the slides.

Workshop: Android Katas

by @corey_latislaw

This one was one of the most fun activities in Droidcon. If you don’t know what kata is, it’s an ancient Japanese practice for martial arts. It’s goal is to internalize the movements by repetitive manner, making slight differences each time so they can be adapted under different circumstances. This was adopted by Software Development to practice writing code, doing it repetitively, build muscle memory.

On the day, I went to all 3 workshops that day. Personally I don’t like Robolectric too much because it can sometimes be painful to setup or find required methods (we did have some problems even with newest version) and it kinda makes testing Robolectric than Android. However, it was a very good practice doing actual TDD (Test Driven Development). All the material we went through can be found here.

You write a test first, stuff even don’t compile, but that’s where Android Studio comes in help as it allows to create those non-existing methods or classes with a click. You fail tests and then you implement those methods, run the test again till it succeeds and you keep going. So at the end your code is going to be documented in tests. Also, it wasn’t mentioned, but if you do TDD, make sure you do it properly.

Useful Android Studio shortcuts mentionedExtract field
You can extract fields to class members, constructors, setUp methods, etc.
option+cmd+fCreate test method
Generates test method, template can be edited in IDE settings, for example method name start with 'shouldDoSomething' rather than 'testSomething'.
cmd+n -> test methodSwitch to test class
Allows to switch between test and class under test, if test class does not exist allows to create one,
cmd+shift+f'Cure for all your problems'
Show intention actions and quick-fixes (not only for imports).
alt+enter

Another reason I write these blog series, it’s like a kata itself, just for writing blogs and deconstructing slides/talks.

Keynote: Managing Expectations: A Manager’s Guide for Managing to Manage Unmanageable Teams Manageably

by Chet, Management Consulting Consultant from Perfect Management Services (PMS)

As the title might suggest it was a very serious talk about very serious stuff. A very detailed one on how to become a project manager and/or consultant (basically upgrade from poor developer position). Covers various management models including famous “Suckling Pigs”.

A must see talk, too much important information to summarize.

Keynote — Android for Java Developers

by @chethaase

Another keynote and talk by another Chet, this time from Google. About Java language in Android ecosystem (context). What works for server Java, may not work for Android (hardware!) Talk based on articles on Medium by Android Developers:

  1. Introduction
  2. Mobile Context
  3. Memory
  4. Performance
  5. Networking
  6. Java and Data Structures
  7. Storage
  8. Framework and Patterns
  9. User Interface
  10. Tools

Mentioned the talk on Devoxx 2013 more about Dalvik and ART runtimes. If you are interested how allocations and garbage collections work, definitely check it out.

Tips for better performance:

  1. Avoid allocations (less allocations = better performance) like creating new Paint() objects in onDraw(…) method. Lint can flag some of these. Cache it by reusing static (if you can manage) or instance variables. Unmanaged static variables can cause activity leaks (on configuration changes, etc…)
  2. If you are allocating large objects constantly, consider using object pools, can be tricky to manage. (LruCache can help you manage it, there is also a disk version here). In a case of low memory system provides callbacks: onLowMemory and onTrimMemory to give you a hint it’s time to do something to free memory. Avoid increasing heap size as it may degrade overall system experience.
  3. Use primitive types like int, float, boolean instead of Integer, Float, Boolean. Use primitive arrays (where you can, especially if you know an exact size) instead of ArrayList. Primitives are a lot cheaper.
  4. Instead of HashMap use ArrayMap, SimpleArrayMap, SparseArray (for smaller data sets, for larger HashMap is fine).
  5. Use methods with mutated objects. For example, instead of Rect getRect(int w, int h) consider void getRect(Rect rect, int w, int h)
  6. Avoid using explicit or implicit iterator allocations (e.g. in for each, for (Object o : myObjects)). Instead, use traditional for loop.
  7. Avoid enums (not completely, still #enumsmatter), use @IntDef annotation instead.
  8. Avoid finalizers to avoid additional garbage collections (use it only if you are dealing with native code).
  9. Avoid excess static initialization (do it lazily). Initialize only when you need it. Will save memory and startup time.
  10. Avoid libraries not written for mobile. For example Guice dependency injection library, which uses reflection, which is not good for performance, instead you can use Dagger, which is more mobile friendly.
  11. Avoid running services longer than needed. Use BroadcastReceiver and/or IntentService.
  12. Optimize for code size. Remove unused code and resources by enabling minifyEnabled true and shrinkResources true in gradle (at least for production code). Don’t use heavy libraries that does so much more than you actually need. Don’t overengineer for simple stuff.

Tools for debugging (with links):

  1. Systrace. Allows to see all junks and holes in a system, CPU frequency, disk activity, etc.
  2. Allocation Tracker. Trace allocations. For example useful for tracking during animation. You start an animation, press start button, press get button and when the animation ends, press end. Observe for GCs etc.
  3. Traceview. Profiling tool. Has two modes: sampling (will bubble up problems and tips) and non-sampling (trace of entire code flow, causes overhead in instrumentation itself, so code can be slower than without tracing, see it as relative time).
  4. Hierarchy Viewer. Displays layout hierarchy. Useful to spot if there is too much nesting in layouts, which causes overhead.
  5. HPROF Viewer. Displays classes, instances of each class, and a reference tree to help you track memory usage and find memory leaks.
  6. Memory and CPU Monitor. Don’t need to setup anything. Displays Memory and CPU usage live.
  7. LeakCanary. A memory leak detection library. Notifies and gives hints when a leak happens.
  8. StrictMode. A tool used to catch accidental disk or network access on the application’s main thread.
  9. Profile GPU Rendering. In developer options in settings. How long does it take various things like rendering, chase if there are any skipped frames.
  10. Debug GPU Overdraw. In developer options in settings. Lets you detect if you are overdrawing layout backgrounds on each other (bad for performance). Use with Hierarchy Viewer.
  11. Animation Duration Scale. In developer options in settings. Slow down to detect any artifacts in animations.
  12. Show hardware layer updates. In developer options in settings. Views backed by a hardware layer that is updated too often can cause performance issues. This tool helps to catch this issue.
#sketchnotes by @corey_latislaw

--

--

Liudas Survila

Android, Clean Code, Software Craftsmanship, UX, Fitness, Science