Tuesday, 29 October 2013

Droidcon 2013: Conquering concurrency — bringing the reactive extensions to the Android platform

Matthias Käppler, Soundcloud @mttkay

Matt has written his own blog post to accompany his talk.

  • this talk is about functional reactive programming
  • but without talking about monads or other mathematical terms
  • example: a list view with data from the server
    • lots of concurrency
    • callbacks, broadcast receivers, notifications all over the place
  • wanted a single event handling model with natural concurrency
  • problem with imperative programming is shared state across whole app
  • doesn’t work with multiple threads and concurrency
  • programming style should reflect the event-based, network-dependent world that apps live in
  • AsyncTask has changed several times in its implementation
    • since ICS it uses a single-threaded executor
    • prone to leaking Context since you have to manage references yourself
    • also has no error handling built-in
    • can’t have long-running tasks that depend on each other
  • event buses (otto, green robot) also have downsides:
    • designed around shared global state
    • still no ability to chain tasks
    • no built-in error handling

RxJava

  • RxJava
    • actually a port of .net Rx extensions invented at Microsoft 5 years ago for Windows Phone
  • Observable<T> ::onNext(T) ::onCompleted ::onError(Throwable)
  • subscribeOn(scheduledThread) / observeOn(scheduledThread)
  • have lots of useful schedulers e.g. observer on main Android thread
  • also have map and mapMany to compose observables

how to use it

  • soundcloud built android extensions
  • http://gihub.com/soundcloud/rxjava
  • dumb fragments
  • service objects implement business objects
  • custom operators for paging content in list views etc
  • AndroidObservables.fromFragment
    • guarantees that it won’t leak but will maintain connection to a rotated activity
  • e.g.

    
    fetchModels(request) { 
    return fetchResponse(request).mapMany((response) -> {
        return mapResponse(request, response);
    })
    }
    

  • simple uniform event model

  • unit tests don’t need to run background threads
  • apply it in a focussed way
  • don’t replace callbacks — used in service layer for API requests
  • use proguard!

downsides

  • java 6 anonymous classes are very verbose
  • deep call stacks in debugging
  • slight increase in GC activity (but didn’t have any noticeable performance impact)
  • learning curve
    • but can use similar things for objective-c and server side (finagle & twitter futures) so can share knowledge

references

No comments: