Contents


android fore

methods lines of code

(if you’re reading this on github –> click here)

A tiny library that helps you write android code in the MVO style that is simple, robust and performant. MVO focusses on the boundary between the view layer the rest of your app, i.e. it helps you implement very clean data binding while supporting rotation by default - no additional work is required.

MVO addresses issues like testability; lifecycle management; UI consistency; memory leaks; and development speed - and if you’re spending time dealing with any of those issues in your code base or team, it’s well worth considering (especially if your current architecture struggles a little when it comes to supporting rotation).

Though the resulting code is often very sparse and clear, there is a considerable amount of thought required to get it to that stage. MVO requires a slight mindset change: the View layer is extremely thin, typically more so than with other architectures.

Quick Start

Latest version: 0.11.1

implementation (group: 'co.early.fore', name: 'fore-core', version: '0.11.1', ext: 'aar')

optional:

implementation (group: 'co.early.fore', name: 'fore-adapters', version: '0.11.1', ext: 'aar')
implementation (group: 'co.early.fore', name: 'fore-retrofit', version: '0.11.1', ext: 'aar')
implementation (group: 'co.early.fore', name: 'fore-lifecycle', version: '0.11.1', ext: 'aar')

See the upgrading guide if you’re coming from an older version.

New to fore

If you’re new to fore, Welcome! might I suggest:

  1. Cloning this git repo
  2. Getting the example apps running (you’ll need at least Android Studio 3)
  3. While referring to the code of the sample apps, dip in to the following sections of the site: MVO Architecture, Views, Models, Data Binding

Method Counts

fore-core methods fore-adapters methods fore-retrofit methods fore-lifecycle methods



fore (though now stable) has been going through iterations privately for more than half a decade - and that privacy has facilitated the focussed removal of surplus functionality and methods, in a way that would probably be more difficult for a public project. The result is an MVO implementation which is particularly small - so small in fact that you could just copy and paste the code into your app if you wanted (it’s small enough to be self-manageable, and the core code hasn’t changed in a while anyway). I’d recommend you just use the JCenter version, but each to their own ;) There’s also no reason you can’t implement MVO yourself of course.

Overview

Due to the sparseness of the resulting view layer code, MVO is particularly scalable with regards to UI complexity, and because of the data binding strategy used, it’s typically very performant. The fore library implementation already supports a number of commercial android applications.

In a nutshell, developing with MVO means:

“Observable Models; Views doing the observing; and some Data Binding tricks to tie it all together”

In MVO (like with most MV* architectures) the model knows nothing about the View. When the view is destroyed and recreated, the view re-attaches itself to the model in line with the observer pattern and syncs its view. Any click listeners or method calls as a result of user interaction are sent directly to the relevant model (no benefit sending them via a Presenter in this case). With this architecture you remove a lot of problems around lifecycle management and handling rotations, it also turns out that the code to implement this is a lot less verbose (and it’s also very testable and scalable).

There are a few important things in MVO that allow you an architecture this simple:

If you totally grok those 4 things, that’s pretty much all you need to use MVO successfully, the code review guide should also come in handy as you get up to speed, or you bring your team up to speed.

The fore library also includes some testable wrappers for AsyncTask: Async and AsyncBuilder (which lets you make use of lambdas)

There are also optional extras that simplify adapter animations and abstract your networking layer when using Retrofit2.

Sample Apps

simple basket

The apps here are deliberately sparse and ugly so that you can see exactly what they are doing. These are not examples for how to nicely structure XML layouts or implement ripple effects - all that you can do later in the View layers and it should have no impact on the stability of the app.

These apps are however, totally robust and comprehensively tested (and properly support rotation). And that’s really where you should try to get to as quickly as possible, so that you can then start doing the fun stuff like adding beautiful graphics and cute animations.

For these sample apps, all the View components are located in the ui/ package and the Models are in the feature/ package. This package structure gives the app code good glanceability and should let you find what you want easily.

For the sample apps there is a one-to-one relationship between the sub-packages within ui/, and the sub-packages within feature/ but it needn’t be like that and for larger apps it often isn’t. You might have one BasketModel but it will be serving both a main BasketView and a BasketIconView located in a toolbar for instance. A more complex view may use data from several different models at the same time eg a BasketModel and an AccountModel.

fore 1 Data Binding Example

video | playstore listing | source code

fore databinding sample app

This app is a bare bones implementation of fore databinding. No threading, no networking, no database access - just the minimum required to demonstrate Data Binding. It’s still a full app though, supports rotation and has a full set of tests to go along with it.

In the app you move money from a “Savings” wallet to a “Mobile” wallet and then back again. Its inspiration is the diagram in the architecture section, although it sadly doesn’t look quite as awesome as that diagram does.

fore 2 Asynchronous Code Example

video | playstore listing | source code

fore threading sample app

This one demonstrates asynchronous programming, and importantly how to test it. It uses (Async and AsyncBuilder). Again, it’s a bare bones (but complete and tested) app - just the minimum required to demonstrate asynchronous programming.

This app has a counter that you can increase by pressing a button (but it takes 20 seconds to do the increasing - during which time you can rotate the device, background the app etc). There are two methods demonstrated, one which allows you to publish progress, and one which lets you take advantage of lambda expressions.

fore 3 Adapter Example

video | playstore listing | source code

fore adapters sample app

This one demonstrates how to use adapters with fore (essentially call notifyDataSetChanged() inside the syncView() method).

It also demonstrates how to take advantage of the built in list animations that Android provides. Once you have set your adapter up correctly, you just call notifyDataSetChangedAuto() inside the syncView() method and fore will take care of all the notify changes work.

Two lists are displayed side to side so you can see the effect this has when adding or removing items. The “Simple” list is on the left, the “Advanced” one that uses notifyDataSetChangedAuto() is on the right.

As usual it’s a complete and tested app but contains just the minimum required to demonstrate adapters.

fore 4 Retrofit Example

video | playstore listing | source code

fore retrofit sample app

Clicking the buttons in this app will perform a network request to some static files that are hosted on Mocky (have you seen that thing? it’s awesome). The first button gets a successful response, the last two get failed responses which are handled in two different ways. The first is a simple error, based on the HTTP code the app receives back from the server. The other is a more specific error based on parsing the body of the error response for an error object. That’s managed by the CallProcessor which is the main innovation in the fore-retrofit library.

As you’re using the app, please notice:

As usual this is a complete and tested app. In reality the tests are probably more than I would do for a real app this simple, but they should give you an idea of how you can do unit testing, integration testing and UI testing whilst steering clear of accidentally testing implementation details when using fore.

fore 5 UI Helpers Example (Tic Tac Toe)

video | playstore listing | source code

fore tic-tac-toe sample app

A regular Tic Tac Toe game that makes use of:

No automated tests for this app (but you should be getting the idea by now - sample apps 1-4 all have comprehensive tests included).

fore 6 DB Example (Room db driven todo list)

video | playstore listing | source code

fore room db sample app

A Todo list on steroids that lets you:

It’s obviously ridiculously contrived, but the idea is to implement something that would be quite challenging and to see how little code you need in the view layer to do it.

It is driven by a Room db, and there are a few distinct architectural layers: as always there is a view layer and a model layer (in packages ui and feature). There is also a networking and a persistence layer. The UI layer is driven by the model which in turn is driven by the db.

All the database changes are done off the UI thread, RecyclerView animations using DiffUtil are supported (for lists below 1000 rows) and the app is totally robust and supports rotation out of the box. For testing, please see example apps 1-4

Other Full App Examples

Contributing

Please read the Code of Conduct, and check out the issues :)

License

Copyright 2017-2018 early.co

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.