Android MVC/MVP/MVVM 框架

网友投稿 676 2022-10-15

Android MVC/MVP/MVVM 框架

Android MVC/MVP/MVVM 框架

AndroidMvc Framework

Features

Easy to implement MVC/MVP/MVVM pattern for Android developmentEnhanced 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 cyclesAll fragment life cycles are mapped into controllers thus logic in life cycles are testable on JVMEasy navigation between pages. Navigation is done in controllers instead of views so navigation can be unit tested on JVMEasy unit test on JVM since controllers don't depend on any Android APIsBuilt in event bus. Event bus also automatically guarantees post event view events on the UI threadAutomatically 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 easyWell 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 CounterMasterControllerCounterDetailScreen 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

@Overridepublic 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 MasterScreennavigationManager.navigate(this).to(CounterMasterController.class);//Verify: location should be changed to MasterScreenAssert.assertEquals(CounterMasterController.class.getName(), navigationManager.getModel().getCurrentLocation().getLocationId());//Act: navigate to DetailScreencontroller.goToDetailScreen(this);//Verify: Current location should be at the view paired with CounterDetailControllerAssert.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 com.shipdream android-mvc [LatestVersion] lib android-mvc-core com.shipdream android-mvc-core [LatestVersion]

Gradle:

lib android-mvccompile "com.shipdream:android-mvc:[LatestVersion]" lib android-mvc-corecompile "com.shipdream:android-mvc-core:[LatestVersion]"

More details on

Website

版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:LeetCode刷题之旅(简单-8):删除排序数组中的重复项
下一篇:SpringMVC(4):加入log4j 包打印日志输出
相关文章

 发表评论

暂时没有评论,来抢沙发吧~