Sample Application for The Android Architecture Talk @ Android Dev Summit 2015.

video

This is a simple social sharing application where users can post text messages and also list other users' messages (feed).

It is written to demonstrate how the application can be designed to work offline and properly sync with the server as network becomes available, with minimal distraction to the user experience.

Disclaimers

This is not an official Google product.

How it works

On the topic of "offline design", many solutions depend on the particular use case but are applicable to different scenarios with small modifications. As such, this demo has its own synching logic and may not 100% match your use case. You should consider it as an example, study and then figure out how to apply a similar approach to your application. Unfortunately, there is no one fits for all solution for offline design.

Here, we'll explain how some of the user interaction flows work, which should give a better idea of what is going on in the application.

The sample project does not religiously follow any particular architectural pattern. Instead, it uses a hybrid approach that fits its own use case. It is designed with the assumption that it will grow into a large application (thus the complexity below). We chose this approach to make the demo as useful and realistic as possible despite the added complexity.

Components

Data Flows

Sending a Post

When a user hits the send button, the first 4 steps are:

  1. Validate post.
  2. Save necessary information to persistent storage about the post (a Job in this case).
  3. Update the PostModel to include the new Post.
  4. Dispatch an event about this new Post.

    (optional) 4.a. If the UI is visible, it updates itself after receiving the event.

Pay attention that the first steps did not include any steps requiring network connection yet we already have up to date information in the user interface and saved the necessary information to eventually sync the Post to server.

  1. Here are the steps for the Job:

    Send Post Job Flow Diagram

Synchronizing Feeds

Synchronizing is managed by 3 components:

Keeping The UI Up to Date

The interaction between background and UI is well defined.

UI components take care of registering/unregistering to the EventBus depending on their lifecycles and since background components never directly reference UI components, we don't risk leaking them.

This is not the only way: The sample app uses a global EventBus. You can implement similar functionality using Rx or hand crafted listeners or any other similar technology. As always, do your own evaluation for your application.

Setup & Run & Tests

Setup

The demo ships with a simple server but you will need Ruby on Rails to run it. The suggested way to install ruby is through Ruby Version Manager. After installing ruby and Rails, you can start the server as follows:

> cd server;
> bundle install;
> rake db:migrate RAILS_ENV=development;

This will install the dependencies of the application and also create the database.

Running

Server

> cd server;
> rails s

Client

The demo app uses the host machine address in an emulator environment by default. (http://10.0.2.2:3000) If you run it in an emulator, it should work just fine, if not, you can change that address in the settings menu or by directly changing DemoConfig class.

Tests

MISC

Avoiding Duplicate Posts

Writing a mobile app means making peace with unreliable network. By using persistent jobs that run when network is available, the demo app does most of the work, but unfortunately it does not end there. `` Under unreliable network conditions, our application may hit a case where the data is saved in the server side but we could never received the success response, so the application still thinks the item is not posted and it will retry. Or even worse, it may happen if our server is having troubles.

Normally, this retry would mean duplication of the item. There are multiple strategies to solve this issue. The demo application uses a unique (userId, clientId) tuple to avoid duplicates. Here is how it works:

You can play with these edge cases by toggling error_before_saving_post and error_after_saving_post in the server/app/controllers/posts_controller.rb.

License

Copyright (C) 2015 The Android Open Source Project

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.

You may obtain a copy of the License at
  http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

See the License for the specific language governing permissions and
limitations under the License.