AndroidMvc


Source link: https://github.com/kejunxia/AndroidMvc

AndroidMvc Framework

Features

  • Easy to implement MVC/MVP/MVVM pattern for Android development
  • Enhanced Android life cycles - e.g. a view needs to refresh when being brought back to foreground but not on rotation, onResume() is not specific enough to differentiate the two scenarios. Android mvc framework provides more granular life cycles
  • All fragment life cycles are mapped into controllers thus logic in life cycles are testable on JVM
  • Easy navigation between pages. Navigation is done in controllers instead of views so navigation can be unit tested on JVM
  • Easy unit test on JVM since controllers don't depend on any Android APIs
  • Built in event bus. Event bus also automatically guarantees post event view events on the UI thread
  • Automatically save and restore instance state. You don't have to touch onSaveInstance and onCreate(savedInstanceState) with countless key-value pairs, it's all managed by the framework.
  • Dependency injection with Poke to make mock easy
  • Well tested - non-Android components are tested as the test coverage shown above (over 90%). For Android dependent module "android-mvc", it's tested by real emulator with this UI test module, even with "Don't Keep Activities" turned on in dev options to guarantee your app doesn't crash due to loss of instance state after it's killed by OS in the background!

More details on

Website

Code quick glance

Let's take a quick glance how to use the framework to navigate between screens first, more details will be discussed later.

The sample code can be found in Here. It is a simple counter app that has a master page and detail page. This 2 pages are represented by two fragments

  • CounterMasterScreen paired with CounterMasterController
  • CounterDetailScreen paired with CounterDetailController

Controller

In CounterMasterController, to navigate simply call

public void goToDetailView(Object sender) {

  //Navigate to CounterDetailController which is paired by CounterDetailScreen
  navigationManager.navigate(sender).to(CounterDetailController.class);
 
}

View

In CounterMasterScreen call the navigation method wrapped by the controller

buttonGoToDetailScreen.setOnClickListener(
  new View.OnClickListener() {

@Override

public void onClick(View v) {

 //Use counterController to manage navigation to make navigation testable

 controller.goToDetailView(v);

}

  
}
);

  

If you use Butterknife, the code can be shorten as below. Also you can use Android Data Binding library to shorten the code similarly

@OnClick(R.id.fragment_master_buttonShowDetailScreen) void goToDetailPage(View v) {

  controller.goToDetailScreen(v);
 
}

In CounterDetailScreen

@Override public void update() {

  /** 
  * Controller will call update() whenever the controller thinks the state of the screen 
  * changes. So just bind the state of the controller to this screen then the screen is always 
  * reflecting the latest state/model of the controller. This is a simple solution but works for most cases. 
  * This solution can be thought as refreshing the whole web page in a browser. If you want more granular  
  * control like ajax to update partial page, define more callbacks in View for MVP pattern and events for MVVM  
  * pattern and call them in the controller when needed. 
  */
  display.setText(controller.getCount());
 
}

Unit test

//Act: navigate to MasterScreen navigationManager.navigate(this).to(CounterMasterController.class);
  //Verify: location should be changed to MasterScreen Assert.assertEquals(CounterMasterController.class.getName(),

navigationManager.getModel().getCurrentLocation().getLocationId());
  //Act: navigate to DetailScreen controller.goToDetailScreen(this);
  //Verify: Current location should be at the view paired with CounterDetailController Assert.assertEquals(CounterDetailController.class.getName(),

navigationManager.getModel().getCurrentLocation().getLocationId());

Division between Views and Controllers

  • View: Mainly fragments that bind user interactions to controllers such as tap, long press and etc. Views reflect the model managed by their controllers.
  • Controller: Controllers expose methods to its view peer to capture user inputs. Once the state of the controller changes, the controller needs to notify its view the update. Usually by calling view.update() or post an event to its view.
  • Model: Represents the state of view and managed by the controller. It can be accessed by controller.getModel(). But only read it to bind the model to views but don't modify the model from views. Modification of model should only be done by controller.
  • Manager: What about controllers have shared logic? Break shared code out into managers. If managers need to access data. Inject services into managers. Managers can be thought as partial controllers serve multiple views through the controllers depending on them.
  • Service: Services are below controller used to access data such as SharedPreferences, database, cloud API, files and etc. It provides abstraction for controllers or managers that can be easily mocked in unit tests for controllers. They the data access layer can be replaced quickly. For example, when some resources are removed from local data to remote data, just simply replace the services implementation to access web api instead of database or sharedPreferences.

See the illustration below

Download

Here is the the latest version number in jCenter

Maven:

  • lib android-mvc

    <dependency>
      <groupId>com.shipdream</groupId>
      <artifactId>android-mvc</artifactId>
      <version>[LatestVersion]</version> </dependency>
  • lib android-mvc-core

    <dependency>
      <groupId>com.shipdream</groupId>
      <artifactId>android-mvc-core</artifactId>
      <version>[LatestVersion]</version> </dependency>

Gradle:

  • lib android-mvc

    compile "com.shipdream:android-mvc:[LatestVersion]"
  • lib android-mvc-core

    compile "com.shipdream:android-mvc-core:[LatestVersion]"

More details on

Website

Resources

A fully open source music player for Android.

Gradle plugin that provides convenience closure for configuring common dependencies.

A paginated gallery for Android with view indicators.

FAImageView is a Frame Animation ImageView for Android.

A material designed colorpicker.

A simple library to show licenses in your android application.

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