Top Banner
Engineering Wunderlist for Android Cesar Valiente +CesarValiente @CesarValiente
39

Engineering Wunderlist for Android - Ceasr Valiente, 6Wunderkinder

Aug 15, 2015

Download

Technology

DroidConTLV
Welcome message from author
This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
Transcript
Page 1: Engineering Wunderlist for Android - Ceasr Valiente, 6Wunderkinder

Engineering Wunderlist for Android

Cesar Valiente

+CesarValiente @CesarValiente

Page 2: Engineering Wunderlist for Android - Ceasr Valiente, 6Wunderkinder

Wunderlist, 6Wunderkinder and me

Page 3: Engineering Wunderlist for Android - Ceasr Valiente, 6Wunderkinder

Together we’ll be better!!

Page 4: Engineering Wunderlist for Android - Ceasr Valiente, 6Wunderkinder

First of all…

• Wunderlist 2 was created as a monolithic app.

• Wunderlist 3 (from now on, just Wunderlist) has been built to be highly independent between layers.

• Real time sync.

Page 5: Engineering Wunderlist for Android - Ceasr Valiente, 6Wunderkinder

1. General architecture

Page 6: Engineering Wunderlist for Android - Ceasr Valiente, 6Wunderkinder

1.2 Three layers

AndroidLayer

SyncLayer

SDKLayer

Presentation layer(UI/Android stuff)

Model layer(Business logic)

Data layer(Accessing to the API data)

Android project Java project Java project

Sync boundaries SDK boundaries

Page 7: Engineering Wunderlist for Android - Ceasr Valiente, 6Wunderkinder

1.3 What does it mean?

• Independent layers. Accessibility.

• Clean architecture.

• Abstract, easy to change, modular —> interfaces.

Page 8: Engineering Wunderlist for Android - Ceasr Valiente, 6Wunderkinder

package com.wunderlist.sdk;

Page 9: Engineering Wunderlist for Android - Ceasr Valiente, 6Wunderkinder

2. Sdk

• Websocket (real time).

• REST.

• Services

• API data models.

• Serializers/deserializers.

• Interfaces/callbacks.

• Sync and async tests.

Network

API model

Page 10: Engineering Wunderlist for Android - Ceasr Valiente, 6Wunderkinder

2.1 Websocket (real time)

“ WebSocket is a protocol providing full-duplex communications channels over a single TCP connection. The WebSocket protocol was standardized by the IETF as RFC 6455 in 2011, and the WebSocket API in Web

IDL is being standardized by the W3C.”

Page 11: Engineering Wunderlist for Android - Ceasr Valiente, 6Wunderkinder

2.1.1 Websocket (real time)

Page 12: Engineering Wunderlist for Android - Ceasr Valiente, 6Wunderkinder

2.1.2 Websocket. Details

• Main way to sync.

• java-websocket, netty,…. OkHttp ws!

Page 13: Engineering Wunderlist for Android - Ceasr Valiente, 6Wunderkinder

2.1.3 Websocket. Mutations void handleMessage(String message) { try { JsonObject jsonObject = Json.parseJson(message); if (HealthResponse.isHealthResponse(jsonObject)) { ……………… } else if (Response.isValidJsonForObject(jsonObject)) { ……………… } else if (Mutation.isValidJsonForObject(jsonObject)) { receiveMutation((Mutation)Json.fromJson(

jsonObject, Mutation.class)); } else { Log.warn("Oh oh! We got a corrupted object on websocket: " + message); } } catch (JsonSyntaxException e) { Log.warn("Discarding a malformed json object on websocket: " + message); } }

Page 14: Engineering Wunderlist for Android - Ceasr Valiente, 6Wunderkinder

2.1.4 Websocket. Real-time example

Page 15: Engineering Wunderlist for Android - Ceasr Valiente, 6Wunderkinder

2.2 REST

• Conventional REST API services for synchronous requests.

• Secondary (fallback) way to sync.

• Using Square OkHttp.

• To encourage hunting bugs and API stress tests, we always use production API.

Page 16: Engineering Wunderlist for Android - Ceasr Valiente, 6Wunderkinder

2.3 Others

• Services, manages an API endpoint (Users, Lists, Tasks, etc.)

• API data models, same structure as API scheme data objects (basic models, just data).

• Json serializers/deserializers. Using Gson. Integrity (health) checks.

• Callbacks.

• Sync/Async unit tests (Junit and mockito) to test requests/responses.

Page 17: Engineering Wunderlist for Android - Ceasr Valiente, 6Wunderkinder

package com.wunderlist.sync;

Page 18: Engineering Wunderlist for Android - Ceasr Valiente, 6Wunderkinder

3. Sync

• Data models.

• Deserializers from the basic model.

• Cache.

• Services that manage data.

• Matryoshka (aka Russian doll).

• Conflict resolver (included in Matryoshka).

This layer manages all business logic of Wunderlist, where we make all sync operations.

Data

Sync logic

Page 19: Engineering Wunderlist for Android - Ceasr Valiente, 6Wunderkinder

3.1 Data models

Sync data models in this layer manage the raw data that we already have from the SDK data models.

public class WLUser extends WLApiObject<User> {

public static Type collectionType = new TypeToken<List<WLUser>>() {}.getType();

@Persist private boolean isMe; private String pictureUrl;

private WLUser(User user) { super(user); }

public static WLUser buildFromBaseModel(User user) { return new WLUser(user); }

public static WLUser buildFromEmail(String email) { …………… } ……………………………………… }

Page 20: Engineering Wunderlist for Android - Ceasr Valiente, 6Wunderkinder

3.2 Deserializers

public class WLTaskDeserializer

extends WLApiObjectDeserializer<Task, WLTask> {

@Override protected Type getType() { return Task.class; }

@Override protected WLTask newInstance(Task baseModel) { return new WLTask(baseModel); } }

• Deserializers make the parsing stuff from the raw API model, to the model we are going to use within the app.

• Our deserializers are used by Gson to work with the correct scheme.

Page 21: Engineering Wunderlist for Android - Ceasr Valiente, 6Wunderkinder

3.3 Cache

• Caches for different models (Tasks, Lists, Memberships, etc.)

• DataStore interface which our database model (in Android layer) and Cache implement to work on the same way.

• Cache has to be filled in a background thread (not UI).

• Two dynamic data structures, List and Map.

Page 22: Engineering Wunderlist for Android - Ceasr Valiente, 6Wunderkinder

3.4 Services• Used to communicate the Android layer with the SDK (AppDataController, retrieves API data).

public class WLTaskService extends WLService<WLTask, TaskService> {

public WLTaskService(Client client) { super(new TaskService(client)); } …………………………

public void getCompletedTasks(final WLList list, final SyncCallback uiCallbacks) { ResponseCallback responseCallback = new ResponseCallback() { @Override public void onSuccess(Response response) { ………………………… uiCallbacks.onSuccess(tasks); } @Override public void onFailure(Response response) { ………………………… uiCallbacks.onFailure(response); } }; service.getCompletedTasksForList(list.getId(), responseCallback); } ………………………… }

Page 23: Engineering Wunderlist for Android - Ceasr Valiente, 6Wunderkinder

3.5. Matryoshka (aka Russian Doll)

Page 24: Engineering Wunderlist for Android - Ceasr Valiente, 6Wunderkinder

3.5.1 What is this?

• Set of wooden dolls of decreasing size placed one inside the other.

• Mechanism to properly sync entire model.

Page 25: Engineering Wunderlist for Android - Ceasr Valiente, 6Wunderkinder

3.5.2 How does it work?

• 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).

Page 26: Engineering Wunderlist for Android - Ceasr Valiente, 6Wunderkinder

3.5.2.1 How does it work?

Page 27: Engineering Wunderlist for Android - Ceasr Valiente, 6Wunderkinder

3.5.2.2 How does it work?

Yay!!! is like a Matryoshka!!! so… is recursive ;-)

Page 28: Engineering Wunderlist for Android - Ceasr Valiente, 6Wunderkinder

package com.wunderlist.wunderlistandroid;

Page 29: Engineering Wunderlist for Android - Ceasr Valiente, 6Wunderkinder

4. Android layer

• This is the UI + Android libs and code.

• Maximized decoupling among UI and business logic.

Page 30: Engineering Wunderlist for Android - Ceasr Valiente, 6Wunderkinder

4.1 Model View Presenter

Presenter(Supervising controller)

Passive view

User events

Updates model

Updates view

State-changes event

Model

Page 31: Engineering Wunderlist for Android - Ceasr Valiente, 6Wunderkinder

4.2 EventBus

• We use EventBus to update the UI when we have loaded asynchronously our requested data…

• … but also when something that we are listen for happens, like a mutation.

EventBus is an Android optimised publish/subscribe event bus. A typical use case for Android apps is gluing Activities, Fragments, and

background threads together.

Page 32: Engineering Wunderlist for Android - Ceasr Valiente, 6Wunderkinder

4.2.1 EventBus (example)

Activity/FragmentA

FragmentB

Code which managesa mutation

(do something that the Activity/Fragment A

uses to update its UI)(this data has to be used

by the Activity/Fragment A)

BUS

Subscription Data Data Data

Page 33: Engineering Wunderlist for Android - Ceasr Valiente, 6Wunderkinder

4.3 Loaders

• We use loaders to request data to our database model/cache.

• The loaders, once they finish, return the data to the Activity/Fragment.

• The loaders can also subscribe themselves to the EventBus and listen for events.

Introduced in Android 3.0, loaders make it easy to asynchronously load data in an activity or fragment.

Page 34: Engineering Wunderlist for Android - Ceasr Valiente, 6Wunderkinder

4.4 Loaders and EventBus (example)

Loader

(Gets the data and does something with it)

Activity/Fragment

DataSource

BUS

Subscription Data Data

Page 35: Engineering Wunderlist for Android - Ceasr Valiente, 6Wunderkinder

4.5 Database

• We can not decuple the Android database (SQLite) here …

• … but we try to make as much abstract as we can the work between data persistence, cache, and API data.

Page 36: Engineering Wunderlist for Android - Ceasr Valiente, 6Wunderkinder

4.6 Others

• We use others useful open source libraries to manage different stuff, like:

- Image management, Square Picasso.

- Network request queue, Path PriorityJobQueue.

Page 37: Engineering Wunderlist for Android - Ceasr Valiente, 6Wunderkinder

Questions?

Page 38: Engineering Wunderlist for Android - Ceasr Valiente, 6Wunderkinder

תודה!!!

+CesarValiente @CesarValiente

Thank you!!!!

Gracias!!!

Page 39: Engineering Wunderlist for Android - Ceasr Valiente, 6Wunderkinder

License

• Content: (cc) 2014-2015 Cesar Valiente Gordo & 6Wunderkinder GmbH. 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/

• All images used in this presentation belong to their owners.