Pilot


Source link: https://github.com/doridori/Pilot

Pilot

Pilot is a way to model the Application State in a familiar ( android.* decoupled) Stack structure, and provides hooks for View based UI Rendering to take place. This facilitates:

  • Single Activity applications
  • A (passive) thin- View based architecture
  • android.*-less app navigation (i.e. Controller -> Controller)
  • An abstract backstack
  • Stack-based data scoping
  • Use of any kind of MV* approach

Why

  • Cleaner, decoupled code
  • Avoiding Fragments is desired for many reasons, not limited to flexibility of how the backstack is used
  • Flexibity of what lives in the backstack enables easy data-scoping for session / screen data as it lives in the stack rather than being passed around or statically based
  • Easy testing
  • As facilitates MV* approaches this means not having to think about asynchronous operations in your UI code (i.e. you can ignore Loaders, RxLifecycle handling or whatever other approach being used to work around the android lifecycle)

Components

Type SRP
PilotStack A Stack of PilotFrame objects
PilotFrame Frame that lives in a PilotStack. May represent a Screen or scoped-data
PilotUISyncer Holds the UITypeHandler collection that is queried upon PilotStack change events
UITypeHandler Interface for an object that can compose a UI for a given set of PilotFrame classes
PilotLifecycleManager Bridge between the hosting Activities lifecycle events and a PilotStack instance
PilotFrameLayout Convenience FrameLayout base for BackedByFrame backed views
@BackedByFrame Annotation to link a PilotFrameLayout to a PilotFrame instance

Seperating Application State from UI Rendering

It can be beneficial to separate the Applications State from the rendering of the UI as really these are separate concerns.

Application State is generally concerned with:

  • What is the user currently doing?
  • What was the user previously doing that can be returned to?
  • What happens if the user decides to do something else?
  • What data is associated with what the user is currently doing?
  • What operations are associated with what the user is currently doing?

UI Rendering is generally concerned with:

  • How can the user visualise what they are currently doing?
  • How does the user return to what they were previously doing?
  • How does the user signify they want to do something else?

The primary win when decoupling in this way is by seperating reponsilbilities testing and refactoring becomes much easier. A secondary advantage is that the Android rendering could be replaced with a terminal, or other type of client.

One design principle is that the Stack should not change regardless of the screen size or rotation. Any master/detail changes (or other size related rendering logic) should sit in the Rendering layer, which in Pilot is abstracted by the UITypeHandler.

Another design priciple is that the Application State should be pure java, to facilitate JVM testing.

Supplementary Aims

To make usage of this project as flexible as possible, the following decisions have been made:

  • Not to tie any consumers to a specific controller type. The reason for this is that all projects have their own approaches in terms of what a Presenter/Controller should be and this is really an orthogonal concern to how the lifecycle and navigation between these controllers is handled. You may prefer to use MVP (Passive View, Supervising Controller, Presentation Model), MVVM or some other variant, this should not impact how the controller layer is managed.

  • Not to require any 3rd party dependencies (e.g. Dagger or RxJava). These (and other) libraries can be used with Pilot but are not essential.

View only?

At present Pilot is for use primarily with View-only UI's. While this seems restrictive I feel adding Fragment support at this point would distract from the main aim of this project. Fragments are great as they are a wrapper for a sub-section of the UI, which have lifecycle callback support and backstack etc. I find when these concepts are pulled out (as they are in Pilot) UI components suddenly become simpler and less bothered about these concepts, and therefore humble View becomes the obvious choice for how to render an applications state, as represented by Pilot.

You may end up with a single- Activity application with nothing but simple Views!

Not the first

Of course I am not the first to think in the way. The guys at Square were talking about very similar things (simple Views and abstract backstack management) years ago - this is a slightly different approach for how to realise those concepts.

Nor am I the last! Conductor is a very similar library which has appeared with the same concepts (and better documentation). Good to see others are thinking along the same lines. I will continue with Pilot however as sure we will have slightly differnt take on things.

EDIT: Moxy and Triad and Magellan and Flowless and ThirtyInch are similar recent repos

Doc Contents

The rest of this README is split across a few doc files:

Usage

repositories {

  maven {

url "https://oss.sonatype.org/content/repositories/snapshots"
  
}
 
}
  dependencies {

  compile 'com.kodroid:pilot:0.10.0-SNAPSHOT' 
}

Proguard

-keepclassmembers class * extends com.kodroid.pilot.lib.android.frameBacking.PilotFrameLayout{
  public <init>(android.content.Context);
 
}
  -keepclassmembers class * extends com.kodroid.pilot.lib.stack.PilotFrame{
  public <init>(com.kodroid.pilot.lib.stack.Args);
 
}
 

WIP

This is a WIP and is currently in development. Some of the supplementary docs also need updating as the project is still undergoing some conceptual refactoring. I am welcome to any input via the Issues page to guide its development. This library is not in use in production yet.

License

Copyright 2015 Dorian Cussen  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. 

Resources

RealmRepository generates classes with access to Realm database. Library uses repository pattern, each generated class supports database operations on certain type. Project was inspired by Spring Data JPA.

Get Appodeal SDK adding just a Gradle dependency line.

Urdu keyboard for android.

Messenger App showing various implementations of Android SMS apis.

Multi Line Radio Group is a Radio Group layout to show radio buttons in more than one line.

Riffsy RecyclerView MVP Grid Example using Dagger 2, Retrofit 2, RxJava 2 and Butterknife with Junit and Espresso tests.

Topics


2D Engines   3D Engines   9-Patch   Action Bars   Activities   ADB   Advertisements   Analytics   Animations   ANR   AOP   API   APK   APT   Architecture   Audio   Autocomplete   Background Processing   Backward Compatibility   Badges   Bar Codes   Benchmarking   Bitmaps   Bluetooth   Blur Effects   Bread Crumbs   BRMS   Browser Extensions   Build Systems   Bundles   Buttons   Caching   Camera   Canvas   Cards   Carousels   Changelog   Checkboxes   Cloud Storages   Color Analysis   Color Pickers   Colors   Comet/Push   Compass Sensors   Conferences   Content Providers   Continuous Integration   Crash Reports   Credit Cards   Credits   CSV   Curl/Flip   Data Binding   Data Generators   Data Structures   Database   Database Browsers   Date &   Debugging   Decompilers   Deep Links   Dependency Injections   Design   Design Patterns   Dex   Dialogs   Distributed Computing   Distribution Platforms   Download Managers   Drawables   Emoji   Emulators   EPUB   Equalizers &   Event Buses   Exception Handling   Face Recognition   Feedback &   File System   File/Directory   Fingerprint   Floating Action   Fonts   Forms   Fragments   FRP   FSM   Functional Programming   Gamepads   Games   Geocaching   Gestures   GIF   Glow Pad   Gradle Plugins   Graphics   Grid Views   Highlighting   HTML   HTTP Mocking   Icons   IDE   IDE Plugins   Image Croppers   Image Loaders   Image Pickers   Image Processing   Image Views   Instrumentation   Intents   Job Schedulers   JSON   Keyboard   Kotlin   Layouts   Library Demos   List View   List Views   Localization   Location   Lock Patterns   Logcat   Logging   Mails   Maps   Markdown   Mathematics   Maven Plugins   MBaaS   Media   Menus   Messaging   MIME   Mobile Web   Native Image   Navigation   NDK   Networking   NFC   NoSQL   Number Pickers   OAuth   Object Mocking   OCR Engines   OpenGL   ORM   Other Pickers   Parallax List   Parcelables   Particle Systems   Password Inputs   PDF   Permissions   Physics Engines   Platforms   Plugin Frameworks   Preferences   Progress Indicators   ProGuard   Properties   Protocol Buffer   Pull To   Purchases   Push/Pull   QR Codes   Quick Return   Radio Buttons   Range Bars   Ratings   Recycler Views   Resources   REST   Ripple Effects   RSS   Screenshots   Scripting   Scroll Views   SDK   Search Inputs   Security   Sensors   Services   Showcase Views   Signatures   Sliding Panels   Snackbars   SOAP   Social Networks   Spannable   Spinners   Splash Screens   SSH   Static Analysis   Status Bars   Styling   SVG   System   Tags   Task Managers   TDD &   Template Engines   Testing   Testing Tools   Text Formatting   Text Views   Text Watchers   Text-to   Toasts   Toolkits For   Tools   Tooltips   Trainings   TV   Twitter   Updaters   USB   User Stories   Utils   Validation   Video   View Adapters   View Pagers   Views   Watch Face   Wearable Data   Wearables   Weather   Web Tools   Web Views   WebRTC   WebSockets   Wheel Widgets   Wi-Fi   Widgets   Windows   Wizards   XML   XMPP   YAML   ZIP Codes