Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Engineering Wunderlist for Android (v2)

Engineering Wunderlist for Android (v2)

In this talk I want to show you how Wunderlist for Android has been built, having a look to the layers of the app, how our sync algorithm woks and also how we are currently changing the architecture of the app to make it better and even more decoupled.


Cesar Valiente

November 17, 2015

More Decks by Cesar Valiente

Other Decks in Programming


  1. Engineering Wunderlist for Android César Valiente

  2. Who is this guy? Image Placeholder César Valiente Android Engineer

    @Wunderlist (@Microsoft) FLOSS & Android Google Developer Expert (GDE) +CesarValiente @CesarValiente
  3. - A very nice and good app. - Monolithic structure.

    - Highly coupled. - Sync in batch. - Difficult to test . Wunderlist 2
  4. Wunderlist 3 - Completely redesigned. - Divided into modules (layers).

    - Highly decoupled. - Real time sync. - Easier to maintain, test and adapt. - Easy to understand.
  5. PARENTAL ADVISORY The following architecture is shared between all Wunderlist

    platforms! yes, iOS, Android, Mac OSX, Web and Windows.
  6. Layers Android Layer Sync Layer SDK Layer Presentation layer (UI

    and Android stuff) Model layer (Business logic) Data layer (Accessing to the API data) Android project Java project Java project Sync boundaries SDK boundaries
  7. Dependency rule The outer model knows the inner, not viceversa.

    Presentation Sync Sdk Interfaces are the key Layered architecture
  8. package com.wunderlist.sdk;

  9. • Websocket (real time). • REST. • Services Network •

    API data models. • Serializers/deserializers. • Interfaces/callbacks. • Sync and async tests. API model SDK
  10. Real time (websocket) Request to setup a web socket connection

    Response to accept the request Payload Payload Close payload Initial handshake Bidirectional flow of packets Closing the connection
  11. Real time (2)

  12. package com.wunderlist.sync;

  13. Sync • Data models. • Deserializers from the basic model.

    • Cache. • Services that manage data. Data • Matryoshka (aka Russian doll). • Conflict resolver (included in Matryoshka). Sync logic
  14. Cache • Caches for different models (Tasks, Lists, Memberships, etc.)

    • DataStore interface which our database model (in presentation layer) and Cache implement to work on the same way. Data interface Store Manager DDBB Cache
  15. Services public class WLTaskService extends WLService<WLTask, TaskService> {

    WLTaskService(Client client) {
 super(new TaskService(client));
 } public void getCompletedTasks(final WLList list, final SyncCallback uiCallbacks) {
 ResponseCallback responseCallback = new ResponseCallback() {
 service.getCompletedTasksForList(list.getId(), responseCallback); } @Override
 public void onSuccess(Response response) { //Manage your response
 uiCallbacks.onSuccess(tasks); } @Override
 public void onFailure(Response response) {
 //Manage your response
  16. Matryoshka (Russian Doll) Mechanism to properly sync entire model. Revision

    based. When a child is updated the revision changes the whole tree up (eg.: when a Task is created the List's revision is incremented, as well the root).
  17. root = Download() CompareRevision(old, root) Outdated? foreach(childType) compareChildren() UpdateChildrenRevisionRoot(root) Publish(root)

    yes no CompareRevision(old, children) foreach(childType) compareChildren() Outdated? Publish(children) yes children = Download() no UpdateChildrenRevisionRoot(children) ………. ………. ……….
  18. root = Download() CompareRevision(old, root) foreach(childType) compareChildren() Outdated? Publish(root) UpdateChildrenRevisionRoot(root)

    yes no Matryoshka is a recursive algorithm!
  19. package com.wunderlist.wunderlistandroid;

  20. Presentation layer • UI + Android libs and code. •

    Maximized decoupling among UI and business logic. • Database, sadly, is located here (native SQLite ddbb).
  21. Communication Activity/Fragment A Fragment B (do something that the Activity/Fragment

    A uses to update its UI) BUS Subscription Data Data Code which manages a mutation (this data has to be used by the Activity/Fragment A) Data
  22. Retrieving local data Loader (Gets the data and does something

    with it) Activity/Fragment BUS Subscription Data Event or data is fired Data
  23. What’s next (WIP)?

  24. Presenter (Supervising controller) Passive view User events Updates model Updates

    view State-changes event Model Model View Presenter (MVP)
  25. Java project Sync (domain) MVP Presentation Interactors (use cases) Repository

    Cache Web socket DDBB REST Data Repository interface Clean Architecture
  26. ? +CesarValiente @CesarValiente

  27. +CesarValiente @CesarValiente Thanks!

  28. License (cc) 2015 César Valiente. Some rights reserved. This document

    is distributed under the Creative Commons Attribution-ShareAlike 3.0 license, available in http:// creativecommons.org/licenses/by-sa/3.0/
  29. Image licenses • Wunderlist and Microsoft images: permission granted. •

    Computer (CC0): http://goo.gl/ChBXuX • Server (CC0): https://goo.gl/WRTm4y • Matryoshka (CC0): http://goo.gl/HWgVa6 • ReactiveX logo (CC-BY 3.0, ReactiveX): http://goo.gl/hK076f