Monday 31 Jul 7 2017
An Android application that captures a subset of the information presented on the https://livetraffic.com web site but in a form more easily digested on a mobile device.
This is the very first Android app I ever wrote, which I have converted from Java to Kotlin as a learning exercise.
The app makes use of these libraries:
- Android Annotations - I mainly use these annotations:
@EActivity
@EFragment
@ViewById
@AfterViews
@FragmentArg
@Extra
@OptionsMenu
@OptionsItem
- Dagger - Dependency injection, switching between test and real implementations of
IDataService
- GSON - For parsing of JSON data files
- RxJava - For asynchronous loading of data
- Timber - For logging
The two fundamental interfaces in the app are IView
and IPresenter
, which represent the
View and Presenter parties in the classic MVP
pattern. The IView
is just a tag interface
implemented by Fragments and Activities that are views. The IPresenter
is generally injected
into the IView
implementation. It attaches itself to the IPresenter
and detaches itself
from the IPresenter
at the appropriate times in its Android lifecycle. Typically the onResume
and onPause
lifecycle methods are the appropriate places to attach and detach the View
from the Presenter.
The following shows IView
and IPresenter
implementations for the Hazards screens. Both the
"Sydney Incidents" and "Regional Incidents" screens use the same Presenter and View classes, just
with different IHazardFilter
implementations applied.
All domain data is retrieved via the IDataService
interface. In production, the RemoteDataService
implementation is used, but for testing the TestDataService
implementation is provided by Dagger
instead. This is achieved by having different Dagger modules defined for each implementation.
HazardsListFragment
tells its Presenter to load Hazards from the Data ServiceHazardsOverviewPresenter
constructs aDownloadHazardsCommand
to perform the download asynchronouslyHazardsOverviewPresenter
constructs aDownloadSuccessHandler
to receive the hazards when they are later returnedHazardsOverviewPresenter
passes theDownloadHazardsCommand
and theSuccesHandler
to theCommandEngine
for asynchronous execution.- The
CommandEngine
executes theDownloadHazardsCommand
asynchronously - The
RemoteDataService
gets theincident.json
file from the remote web server and... - ... returns them to the
DownloadSuccessHandler
for parsing into data objects. - The resulting List of Hazards is stored away in the
HazardCacheSingleton
for future reference - The
DownloadSuccessHandler
, via theHazardOverviewPresenter
, tells the view (HazardListFragment
) to refresh its display of Hazards because new hazard data is now available in theHazardCacheSingleton
- The
HazardListFragment
constructs a newHazardListAdapter
which interrogates theHazardCacheSingleton
for its new data which is then used to populate the Hazards List on the screen.
The Navigation drawer slides out from left of top level screens.
A list of Hazards (Incidents) in Regional NSW, grouped by RMS Region.
Details screen for an individual Incident.
Clicking the Location icon on the Hazards Detail screen shows the GPS location of the Incident.
List of traffic cameras in the Sydney area, grouped by RMS Region.
Image from an individual traffic camera. Images update on the server every minute. The star action toggles the inclusion of this camera in the "Favourite Cameras" set.
Travel Times on the M1 Motorway. Touching individual rows toggles the rows' travel time in and out of the total travel time for a given direction of travel on the Motorway.