34.Android MVC框架 - Robotlegs4Androird
来源:互联网 发布:温莎公爵知乎 编辑:程序博客网 时间:2024/05/23 19:14
34.Android MVC框架 - Robotlegs4Androird
- Android MVC框架 - Robotlegs4Androird
- Android 耦合的MVC
- Robotlegs4Android MVC
- Robotlegs4Android Gradle
- Robotlegs4Android Github
- Robotlegs4Android Model
- Robotlegs4Android View
- Robotlegs4Android Activity
- Robotlegs4Android Fragment
- Robotlegs4Androird Event
- Robotlegs4Android Controller
- Robotlegs4Android Context
- Robotlegs4Android Application
- Event View to Controller
- Event Model to Controller
- Event Model to View
- Event Controller to View
Android 耦合的MVC
说到Android上的MVC,还真的不好区分。很多时候都是这样的,View层和Controller层总是傻傻分不清楚。
Model层显而易见的是各种bean(实体),配上 gson 或者 fastjson 解析网络请求回来的json,生成各种实例。
但是,在View层的 Activity 或 Fragment 上,虽然有View层的理念,避免不了很多Controller层的业务过度耦合在View层。
总结得出,View层(Activity、Fragment)除了自身的生命周期回调方法(onCreate、onStart … 等)外,还掺杂了各种Controller业务(直接操作Model、DB操作 … 等)
反正就是,各种乱七八糟的东西都放在Activity 或 Fragment,各种难看,各种耦合。
在这种情况下,衍生出了 MVP 和 MVVM 。现在主流的还是MVP,MVVM目前在Android上还不成熟,还处于测试阶段。
Robotlegs4Android MVC
这是Robotlegs4Android 的 MVC 流程图。
- EventDispatcher 完成各层之间的通信。
- Mediator 代理 View 层的业务,View层只显示简单的生命周期回调方法。
- Command 作为 Controller 层,对 View 传过来的业务进行相应处理。
- Actor 作为 Model 层,为 Command 提供 DB 的请求(SQLite 或 网络请求)。
Robotlegs4Android Gradle
dependencies { compile 'com.camnter.robotlegs4android:robotlegs4android:0.8'}
Robotlegs4Android Github
Robotlegs4Android
Robotlegs4Android Model
extends Actor
定义一个Robotlegs4Android Model对象,只需要继承 Actor 即可。
UserModel
public class UserModel extends Actor { public void login(String name,String password) { // TODO Do you want to network requests } public boolean logout(){ // TODO Do you want to network requests return true; }}
User
public class User implements Serializable { public String name; public String sign;}
Robotlegs4Android View
- Robotlegs4Android Activity
- Robotlegs4Android Fragment
Robotlegs4Android Activity
- 如果你这个Activity不需要Fragment。
extends RobotlegsActivity
。 - 如果你这个Activity需要Fragment。
extends RobotlegsFragmentActivity
。
MainActivity (看起来真的很简单)
public class MainActivity extends RobotlegsFragmentActivity { /** * Please set the fragment layout id * 请设置Fragment的布局Id * * @return */ @Override public int getLayoutId() { return R.layout.activity_main; } @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); }}
MainActivityMediator(这里处理Activity要做的事情)
public class MainActivityMediator extends Mediator { private static final String TAG = "MainActivityMediator"; private MainActivity activity; private TabLayout tabLayout; private ViewPager viewPager; /** * {@inheritDoc} * {@linkplain IMediator #onRegister} */ @Override public void onRegister() { this.activity = (MainActivity) this.getViewComponent(); this.initViews(); this.initData(); } private void initViews() { this.tabLayout = (TabLayout) this.activity.findViewById(R.id.tab_layout_tl); this.viewPager = (ViewPager) this.activity.findViewById(R.id.view_pager_vp); } private void initData() { String[] tabTitles = {"ONE", "TWO", "THR", "FOU"}; Fragment[] fragments = { TabLayoutFirstFragment.getInstance(), TabLayoutSecondFragment.getInstance(), TabLayoutThirdFragment.getInstance(), TabLayoutFourthFragment.getInstance() }; MainActivityAdapter adapter = new MainActivityAdapter(this.activity.getSupportFragmentManager(), fragments, tabTitles); this.viewPager.setAdapter(adapter); this.tabLayout.setupWithViewPager(this.viewPager); }}
Robotlegs4Android Fragment
extends RobotlegsFragment
TabLayoutFirstFragment(看起来真的很简单)
public class TabLayoutFirstFragment extends RobotlegsFragment { private static TabLayoutFirstFragment instance; private TabLayoutFirstFragment() { } public static TabLayoutFirstFragment getInstance() { if (instance == null) instance = new TabLayoutFirstFragment(); return instance; } /** * Please set the fragment layout id * 请设置Fragment的布局Id * * @return */ @Override public int getLayoutId() { return R.layout.tablayout_first_fragment; }}
TabLayoutFirstFragmentMediator(这里处理Fragment要做的事情)
public class TabLayoutFirstFragmentMediator extends Mediator implements View.OnClickListener { public TabLayoutFirstFragment fragment; public FragmentActivity activity; private Button firstBT; private TextView firstTV; private ImageView firstIV; private TextView controllerTV; /** * {@inheritDoc} * {@linkplain IMediator #onRegister} */ @Override public void onRegister() { this.fragment = (TabLayoutFirstFragment) this.getViewComponent(); this.activity = this.fragment.getActivity(); this.initViews(); this.initData(); } private void initViews() { this.firstBT = (Button) this.fragment.self.findViewById(R.id.first_bt); this.firstTV = (TextView) this.fragment.self.findViewById(R.id.first_tv); this.firstIV = (ImageView) this.fragment.self.findViewById(R.id.first_iv); this.controllerTV = (TextView) this.fragment.self.findViewById(R.id.first_controller_tv); } private void initData() { this.firstTV.setText("The ONE created by robotlegs4android frame"); } /** * Called when a view has been clicked. * * @param v The view that was clicked. */ @Override public void onClick(View v) { switch (v.getId()) { case R.id.first_bt: { } } }}
Robotlegs4Androird Event
extends com.camnter.robotlegs4android.base.Event
为了各个层之间的通信,定义一个Event类型。
LoginEvent
public class LoginEvent extends Event { public static final String USER_LOGIN = "user_login"; public static final String USER_LOGOUT = "user_logout"; public static final String USER_LOGIN_SUCCESS_FROM_MODEL_TO_CONTROLLER = "user_login_success_from_model_to_controller"; public static final String USER_LOGIN_SUCCESS_FROM_MODEL_TO_VIEW = "user_login_success_from_model_to_view"; public static final String USER_LOGIN_SUCCESS_FROM_CONTROLLER_TO_VIEW = "user_login_success_from_controller_to_view"; public String name; public String password; public User user; public LoginEvent(String type) { super(type); }}
Robotlegs4Android Controller
extends Command
有了通讯,自然也要有Controller去处理,发向Controller的事件。
Login
public class Login extends Command { private static final String TAG = "Login"; @Inject public UserModel userModel; @Inject public LoginEvent event; /** * TODO - The Command subclass must inherit the execute method * 备忘录 - Command子类必须继承execute方法 */ @Override public void execute() { switch (event.getType()) { case LoginEvent.USER_LOGIN: { userModel.login(event.name, event.password); break; } case LoginEvent.USER_LOGOUT: { userModel.logout(); break; } case LoginEvent.USER_LOGIN_SUCCESS_FROM_MODEL_TO_CONTROLLER: { break; } } }
!!!!!! Robotlegs4Android Context
extends com.camnter.robotlegs4android.mvcs.Context
必须定义一个com.camnter.robotlegs4android.mvcs.Context
- 1.为了配置View和对应Mediator。
- 2.为了单例注入Model(Actor)。
- 3.为了配置传入Controller(Command)的事件。
MainContext
public class MainContext extends Context { public MainContext(Object contextView, Boolean autoStartup) { super(contextView, autoStartup); } /** * set your mvc relation * 设置你的mvc关系 * <p/> * Add the view map * Link the View and View the corresponding Mediator * 添加view映射 * 将View 和 View 对应的 Mediator 联系起来 * <p/> * Injection as an singleton, instantiate the singleton * 注入实例,实例化单例 * <p/> * Add Event (Event) with the connection of the Command * 添加事件(Event)与Command的联系 */ @Override public void setMvcRelation() { /* * view映射 * 将View 和 View 对应的 Mediator 联系起来 * Add the view map * Link the View and View the corresponding Mediator */ this.getMediatorMap().mapView(MainActivity.class, MainActivityMediator.class, null, true, true); this.getMediatorMap().mapView(TabLayoutFirstFragment.class, TabLayoutFirstFragmentMediator.class, null, true, true); this.getMediatorMap().mapView(TabLayoutSecondFragment.class, TabLayoutSecondFragmentMediator.class, null, true, true); this.getMediatorMap().mapView(TabLayoutThirdFragment.class, TabLayoutThirdFragmentMediator.class, null, true, true); this.getMediatorMap().mapView(TabLayoutFourthFragment.class, TabLayoutFourthFragmentMediator.class, null, true, true); /* * 注入实现 实例化单例 * Injection as an singleton, instantiate the singleton */ this.getInjector().mapSingleton(UserModel.class, ""); /* * 添加事件与Command的联系 * Add Event (Event) with the connection of the Command */ this.getCommandMap().mapEvent(LoginEvent.USER_LOGIN, Login.class, null, false); this.getCommandMap().mapEvent(LoginEvent.USER_LOGIN_SUCCESS_FROM_MODEL_TO_CONTROLLER, Login.class, null, false); }}
!!!!!! Robotlegs4Android Application
extends RobotlegsApplication
必须定义一个Robotlegs4Android Application去初始化,对应的Robotlegs4Android Context
MainApplication
public class MainApplication extends RobotlegsApplication { private static MainApplication ourInstance = new MainApplication(); public static MainApplication getInstance() { return ourInstance; } /** * Please write your custom robotlegs4android context * 请填写你自定义的robotlegs4android context * TODO After write your custom robotlegs4android context, please don't call this method * TODO 填写完你自定义的robotlegs4android context后,请不要调用此方法 * * @return */ @Override protected Context getMvcContextInstance() { return new MainContext(this, true); } /** * Called when the application is starting, before any activity, service, * or receiver objects (excluding content providers) have been created. * Implementations should be as quick as possible (for example using * lazy initialization of state) since the time spent in this function * directly impacts the performance of starting the first activity, * service, or receiver in a process. * If you override this method, be sure to call super.onCreate(). */ @Override public void onCreate() { super.onCreate(); if (ourInstance == null) ourInstance = this; }}
AndroidManifest.xml
<application android:name="com.camnter.robotlegs4android.test.application.MainApplication" android:allowBackup="true" android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:theme="@style/AppTheme"> <activity android:name=".view.activity.MainActivity" android:label="@string/app_name"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> </application>
Event View to Controller
TabLayoutFirstFragmentMediator 发送一个LoginEvent.USER_LOGIN的LoginEvent。
/** * Called when a view has been clicked. * * @param v The view that was clicked. */ @Override public void onClick(View v) { switch (v.getId()) { case R.id.first_bt: { /* * you can send a your custom event from Model layer to Controller layer,and the * frame will search the event configuration from your custom context * 你可以发送一个你自定义的事件从Model层到Controller层,并且框架会去你自定义的context搜索 * 这个事件的配置 */ LoginEvent loginEvent = new LoginEvent(LoginEvent.USER_LOGIN); loginEvent.name = "CaMnter"; loginEvent.password = "Save you from anything"; this.dispatch(loginEvent); } } }
MainContext 设置了LoginEvent.USER_LOGIN事件的去向的Controller。
this.getCommandMap().mapEvent(LoginEvent.USER_LOGIN, Login.class, null, false);
Login 的execute()
方法能拿到LoginEvent.USER_LOGIN事件。
@Inject public LoginEvent event; /** * TODO - The Command subclass must inherit the execute method * 备忘录 - Command子类必须继承execute方法 */ @Override public void execute() { switch (event.getType()) { case LoginEvent.USER_LOGIN: { userModel.login(event.name, event.password); break; } case LoginEvent.USER_LOGOUT: { userModel.logout(); break; } case LoginEvent.USER_LOGIN_SUCCESS_FROM_MODEL_TO_CONTROLLER: { Log.i(TAG, "This Login Controller know the user login success"); /* * send an USER_LOGIN_SUCCESS_FROM_CONTROLLER_TO_VIEW type of event to View layer * 发送一个USER_LOGIN_SUCCESS_FROM_CONTROLLER_TO_VIEW类型的事件到View层 */ this.dispatch(new LoginEvent(LoginEvent.USER_LOGIN_SUCCESS_FROM_CONTROLLER_TO_VIEW)); break; } } }
Event Model to Controller
UserModel 的login(String name,String password)
方法发送一个LoginEvent.USER_LOGIN_SUCCESS_FROM_MODEL_TO_CONTROLLER的LoginEvent。
public void login(String name,String password) { // TODO Do you want to network requests User user = new User(); user.name = "CaMnter"; user.sign = "Save you from anything"; /* * you can send a your custom event from Model layer to Controller layer * 你可以发送一个你自定义的事件从Model层到Controller层 */ this.dispatch(new LoginEvent(LoginEvent.USER_LOGIN_SUCCESS_FROM_MODEL_TO_CONTROLLER)); }
Event Model to View
UserModel 的login(String name,String password)
方法再发送一个LoginEvent.USER_LOGIN_SUCCESS_FROM_MODEL_TO_VIEW的LoginEvent。
public void login(String name,String password) { // TODO Do you want to network requests User user = new User(); user.name = "CaMnter"; user.sign = "Save you from anything"; /* * you can send a your custom event from Model layer to View layer * 你可以发送一个你自定义的事件从Model层到View层 */ LoginEvent loginEvent = new LoginEvent(LoginEvent.USER_LOGIN_SUCCESS_FROM_MODEL_TO_VIEW); loginEvent.user = user; this.dispatch(loginEvent); /* * you can send a your custom event from Model layer to Controller layer * 你可以发送一个你自定义的事件从Model层到Controller层 */ this.dispatch(new LoginEvent(LoginEvent.USER_LOGIN_SUCCESS_FROM_MODEL_TO_CONTROLLER)); }
Mediator.getEventMap().mapListener(IEventDispatcher dispatcher, String type,IListener listener, Class<?> eventClass, Boolean useCapture,int priority, Boolean useWeakReference)
TabLayoutFirstFragmentMediator 添加对LoginEvent.USER_LOGIN_SUCCESS_FROM_MODEL_TO_VIEW类型的LoginEvent的监听。
*/ @Override public void onRegister() { this.fragment = (TabLayoutFirstFragment) this.getViewComponent(); this.activity = this.fragment.getActivity(); this.initViews(); this.initData(); this.initListeners(); } private void initViews() { this.firstBT = (Button) this.fragment.self.findViewById(R.id.first_bt); this.firstTV = (TextView) this.fragment.self.findViewById(R.id.first_tv); this.firstIV = (ImageView) this.fragment.self.findViewById(R.id.first_iv); this.controllerTV = (TextView) this.fragment.self.findViewById(R.id.first_controller_tv); } private void initData() { this.firstTV.setText("The ONE created by robotlegs4android frame"); } private void initListeners() { this.firstBT.setOnClickListener(this); /* * listening your custom event(such as listening to an USER_LOGIN_SUCCESS type of LoginEvent) * listening from Model layer to View layer in here * 监听你的自定义事件(例如监听一个USER_LOGIN_SUCCESS_FROM_MODEL_TO_CONTROLLER_AND_VIEW类型的LoginEvent) * 在这里监听从Model层到View层 */ this.getEventMap().mapListener(this.getEventDispatcher(), LoginEvent.USER_LOGIN_SUCCESS_FROM_MODEL_TO_VIEW, new Listener() { /** * {@inheritDoc} * <p/> * {@linkplain IListener #onHandle} * * @param event */ @Override public void onHandle(Event event) { if (event instanceof LoginEvent) { TabLayoutFirstFragmentMediator.this.firstIV.setVisibility(View.VISIBLE); } } }, null, false, 0, true); }
Event Controller to View
Login 发送一个LoginEvent.USER_LOGIN_SUCCESS_FROM_CONTROLLER_TO_VIEW类型的LoginEvent。
/** * TODO - The Command subclass must inherit the execute method * 备忘录 - Command子类必须继承execute方法 */ @Override public void execute() { switch (event.getType()) { case LoginEvent.USER_LOGIN: { userModel.login(event.name, event.password); break; } case LoginEvent.USER_LOGOUT: { userModel.logout(); break; } case LoginEvent.USER_LOGIN_SUCCESS_FROM_MODEL_TO_CONTROLLER: { Log.i(TAG, "This Login Controller know the user login success"); /* * send an USER_LOGIN_SUCCESS_FROM_CONTROLLER_TO_VIEW type of event to View layer * 发送一个USER_LOGIN_SUCCESS_FROM_CONTROLLER_TO_VIEW类型的事件到View层 */ this.dispatch(new LoginEvent(LoginEvent.USER_LOGIN_SUCCESS_FROM_CONTROLLER_TO_VIEW)); break; } } }
Mediator.getEventMap().mapListener(IEventDispatcher dispatcher, String type,IListener listener, Class<?> eventClass, Boolean useCapture,int priority, Boolean useWeakReference)
TabLayoutFirstFragmentMediator 再添加一个对LoginEvent.USER_LOGIN_SUCCESS_FROM_CONTROLLER_TO_VIEW类型的LoginEvent的监听。
/** * {@inheritDoc} * {@linkplain IMediator #onRegister} */ @Override public void onRegister() { this.fragment = (TabLayoutFirstFragment) this.getViewComponent(); this.activity = this.fragment.getActivity(); this.initViews(); this.initData(); this.initListeners(); } private void initViews() { this.firstBT = (Button) this.fragment.self.findViewById(R.id.first_bt); this.firstTV = (TextView) this.fragment.self.findViewById(R.id.first_tv); this.firstIV = (ImageView) this.fragment.self.findViewById(R.id.first_iv); this.controllerTV = (TextView) this.fragment.self.findViewById(R.id.first_controller_tv); } private void initData() { this.firstTV.setText("The ONE created by robotlegs4android frame"); } private void initListeners() { this.firstBT.setOnClickListener(this); /* * listening your custom event(such as listening to an USER_LOGIN_SUCCESS type of LoginEvent) * listening from Model layer to View layer in here * 监听你的自定义事件(例如监听一个USER_LOGIN_SUCCESS_FROM_MODEL_TO_CONTROLLER_AND_VIEW类型的LoginEvent) * 在这里监听从Model层到View层 */ this.getEventMap().mapListener(this.getEventDispatcher(), LoginEvent.USER_LOGIN_SUCCESS_FROM_MODEL_TO_VIEW, new Listener() { /** * {@inheritDoc} * <p/> * {@linkplain IListener #onHandle} * * @param event */ @Override public void onHandle(Event event) { if (event instanceof LoginEvent) { TabLayoutFirstFragmentMediator.this.firstIV.setVisibility(View.VISIBLE); } } }, null, false, 0, true); /* * listening your custom event(such as listening to an USER_LOGIN_SUCCESS type of LoginEvent) * listening from Controller layer to View layer in here * 监听你的自定义事件(例如监听一个USER_LOGIN_SUCCESS_FROM_CONTROLLER_TO_VIEW类型的LoginEvent) * 在这里监听从Controller层到View层 */ this.getEventMap().mapListener(this.getEventDispatcher(), LoginEvent.USER_LOGIN_SUCCESS_FROM_CONTROLLER_TO_VIEW, new Listener() { /** * {@inheritDoc} * <p/> * {@linkplain IListener #onHandle} * * @param event */ @Override public void onHandle(Event event) { if (event instanceof LoginEvent) { TabLayoutFirstFragmentMediator.this.controllerTV.setVisibility(View.VISIBLE); } } }, null, false, 0, true); }
- 34.Android MVC框架 - Robotlegs4Androird
- android 中 MVC框架
- Android之MVC框架
- Android的MVC框架
- Android MVC框架模式
- Android 框架MVC详解
- Android MVC框架
- android MVC 框架的详解
- Android 初识 MVC、MVP框架
- Android之MVC MVP框架
- Android中的 框架模式 MVC
- Android 初识 MVC、MVP框架
- 【Android】【设计】Android 框架 MVC,MVP,MVVM
- Android中采用的MVC框架
- Android中采用的MVC框架
- Android中采用的MVC框架
- android代码重构之MVC框架
- android应用开发MVC框架(一)
- android 源码文件结构
- Cocos2d-js中Chipmunk引擎
- java中实现代理及委托代理模式
- appium对键盘处理
- 回射客户端服务器UDP(echo client&&server based on UDP)
- 34.Android MVC框架 - Robotlegs4Androird
- sublime text 安装插件
- 使用https出错javax.net.ssl.SSLHandshakeException: Handshake failed
- spring、struct、hibernate三大框架整合
- python datetime详解
- Hibernate基于主键的多对多映射2015-11-11
- 线性表
- 蓝懿iOS 技术内容交流和学习心得 11.11
- PostgreSQL安全指南 - Postgres2015全国用户大会--重磅嘉宾佳作分享(周正中)