Contents


android fore

license-apache2

jcenter-1.1.3

api-16

circleci

year asafcore and forecore jcenter downloads 2018 Nov 18



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

fore helps you move code out of the view layer. Because once you do that, magical things start to happen.

The most important class in the fore library is the observable implementation. This very simple class lets you make anything observable (usually it’s models & repositories that are made observable, things in the view layer like activities & fragments do the observing).


public class AccountRepository extends ObservableImp {

  public AccountRepository(WorkMode workMode) {
    super(workMode);
  }

  ...

}
 

class AccountRepository(workMode: WorkMode) :
          Observable by ObservableImp(workMode) {

  ...

}
 

The fore observable has two different WorkModes:

The core package is tiny (126 methods and about 500 lines of code), so you can just use the observer to immediately make your view layer reactive and testable, or go full on MVO and wonder where all your code went ;)

The view layer is particularly sparse when implementing MVO with fore and the apps are highly scalable from a complexity standpoint, so fore works for both quick prototypes, and large complex commercial projects with 100K+ lines of code.

Specifically why it is that apps written this way are both sparse and scalable is not always immediately obvious. This dev.to article details the whys and the hows of converting the Android Architecture Blueprint Todo sample app from MVP to MVO (and in doing so drops the lines of code count by about half). This discussion also gets into the design of the fore api and why it drastically reduces boiler plate for a typical android app. But these are subtle, advanced topics that are not really necessary to use fore at all - most of the actual code in the fore library is quite simple.

Quick Start

for a more kotlin style API and running coroutines under the hood:

implementation "co.early.fore:fore-kt:1.1.3"

the original java:

implementation "co.early.fore:fore-jv:1.1.3"

Those two packages above won’t co-exist in the same app, so if you have an app that is half-java and half-kotlin, or if you just want a subset of the features, you can use any of these packages in any combination you like:

implementation "co.early.fore:fore-core:1.1.3"
implementation "co.early.fore:fore-adapters:1.1.3"
implementation "co.early.fore:fore-lifecycle:1.1.3"
implementation "co.early.fore:fore-retrofit:1.1.3"

//backed by coroutines rather than threads
//but just as testable, and slightly more kotliny
implementation "co.early.fore:fore-core-kt:1.1.3"
implementation "co.early.fore:fore-retrofit-kt:1.1.3"

(pre-androidX use version 0.11.1 fore-core, fore-adapters, fore-lifecycle, fore-retrofit)

If you want to check what versions of what dependencies each package pulls in, the definitive answer is found in the pom files hosted at jcenter. See the release notes 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 (run ./gradlew publishToMavenLocal after cloning if AS gives you red squiggles)
  2. Getting the example apps running (you’ll need AS4 - git checkout tags/v1.1.0 if you’re still on AS3)

Then either

Check out some of the tutorials on dev.to like this one which demonstrates how the syncView() convention helps you to write less code, while removing a whole class of UI consistency bugs from the UI layer.

Or

While referring to the code of the sample apps, dip in to the following sections of this site: MVO Architecture, Views, Models, Reactive UIs

Method Counts

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



Using fore and a few techniques outlined in these docs, you can quickly and robustly implement android apps in the MVO architectural style (it’s like a radically reduced version of MVVM, with the addition of a render() style function similar to MVI/Redux, or like MvRx’s invalidate() function - it’s called syncView() in MVO). It usually results in much less code in the view layer, rock-solid UI consistency, great testability, and support for rotation by default.

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

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 but surprisingly powerful (just 534 lines of code for the core package).

Overview

In a nutshell, developing with fore means writing:

“Observable Models; Views doing the observing; and some Reactive UI 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. 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 fore 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 (that Google should have provided, but didn’t): Async and AsyncBuilder - which supports lambdas making using them alot nicer to use.

If you’ve moved over to using coroutines already, a few fore extension functions are all you need to use coroutines in a way that is completely testable (something that is still pending in the official release).

There are also optional extras that simplify adapter animations and abstract your networking layer when using Retrofit2. fore works really well with RoomDB too, checkout the last sample app for details.

Sample Apps

all samples

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 Reactive UI Example

video | playstore listing | source code (java)

fore reactive UI sample app

This app is a bare bones implementation of fore reactive UIs. No threading, no networking, no database access - just the minimum required to demonstrate Reactive UIs. 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 (java) | source code (kotlin)

fore threading sample app

This one demonstrates asynchronous programming, and importantly how to test it. The java version uses (Async and AsyncBuilder), the kotlin version uses coroutines (with some fore extensions that make the coroutines unit testable). 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 time to do the increasing - so you can rotate the device, background the app etc and see the effect). There are two methods demonstrated: one which uses lambda expressions (for java), and one which publishes progress.

fore 3 Adapter Example

video | playstore listing | source code (java) | source code (kotlin)

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. (You could also use fore’s’ notifyDataSetChangedAuto() to do this for you from your render() function if you’re using MVI / MvRx or some flavour of Redux).

The java sample has two lists side by 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.

The kotlin version has three lists, all of which use adapter animations. The first list uses google’s AsyncListDiffer (which is what drives ListAdapter), the second list uses fore’s Updatable (which uses android’s notifyItem… methods for a very efficient animated adapter implementation), the third list uses fore’s Diffable (which relies on DiffUtil under the hood). All three implementations have slightly different characteristics, check the source code for further infomation.

fore 4 Retrofit Example

video | playstore listing | source code (java) | source code (kotlin)

fore retrofit sample app

Clicking the buttons in this app will perform network requests to some static files that are hosted on Mocky (have you seen that thing? it’s awesome). The buttons make various network connections, various successful and failed responses are handled in different ways. It’s all managed by the CallProcessor class which is the main innovation in the fore-retrofit library, the kotlin implementation of CallProcessor is implemented with coroutines and has an API better suited to kotlin and functional programming.

As you’re using the app, please notice:

  • how you can rotate the device with no loss of state or memory leaks. I’ve used Mocky to add a delay to the network request so that you can rotate the app mid-request to clearly see how it behaves (because we have used fore to separate the view from everything else, rotating the app makes absolutely no difference to what the app is doing, and the network busy spinners remain totally consistent). Putting the device in airplane mode also gives you consistent behaviour when you attempt to make a network request.

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 (java)

fore tic-tac-toe sample app

A regular Tic Tac Toe game that makes use of:

  • The SyncXXX lifecycle convenience classes which reduce boiler plate slightly and automatically handle the adding and removing of observers in line with various lifecycle methods

  • SyncTrigger which bridges the gap between the observer pattern and one off triggers that you want to fire (such as displaying a win animation at the end of a game)

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 to-do list)

video | playstore listing | source code (java)

fore room db sample app

A To-do list on steroids that lets you:

  • manually add 50 random todos at a time
  • turn on a “boss mode” which randomly fills your list with even more todos over the following 10 seconds
  • “work from home” which connects to the network and downloads 25 extra todos (up to 9 simultaneous network connections)
  • randomly delete about 10% of your todos
  • randomly change 10% of your outstanding todos to done

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), the app is totally robust and supports rotation out of the box. There is a TodoListModel written in Java and one in Kotlin for convenience, in case you are looking to use these as starting points for your own code.

There is only one test class included with this app which demonstrates how to test Models which are driven by a Room DB (using CountdownLatches etc). For other test examples, please see sample apps 1-4

Tutorials

  • There is a short series of dev.to tutorials which include more sample apps covering the basics of fore here

Other Full App Examples

  • There is a full app example hosted in a separate repo written in Kotlin here

Contributing

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

License

Copyright 2015-2020 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.