Flux--Hello World

来源:互联网 发布:js对象排序函数 编辑:程序博客网 时间:2024/06/07 22:27

这是一个极简的HelloWorld应用,主要用来展示如何在Android平台架构Flux应用。并提供一些基础代码,方便开发者直接Copy这些代码到自己的工程中,省掉重新造轮子的过程。代码地址在Flux-HelloWorld,接下来会一步步的解释这个应用是如何构建的。

Demo程序是用AndroidStudio开发的,假设你已经了解Android和AndroidStudioIDE,如果你已经很熟悉Android应用的开发,看完AndroidFlux一览或许已经可以开发出基于Flux框架的应用,如果你并不熟悉Flux或者Android,务必先读完这篇文档

源码结构 

本着架构即目录的思想,让我们先看一下源码结构,整个的源码结构是这样的:


这里包含4个目录和一个文件:

  1. MainActivity.java Flux框架中的Controller-View部分,在Android中可以是Activity或者Fragment
  2. actions Flux框架中的Action部分,存放不同类型的XXXAction.javaActionsCreator.java文件
  3. dispatcher Flux框架中的Dispatcher部分,存放 Dispatcher.java 文件,一个应用中只需要一个Dispatcher
  4. model 存放各种业务逻辑相关的Model文件
  5. stores Flux框架中的Stores部分,存在各种类型的 XXXStore.java 文件

创建一个Dispatcher 

在AndroidFlux中Dispatcher是就是一个发布-订阅模式。Store会在这里注册自己的回调接口,Dispatcher会把Action分发到注册的Store,所以它会提供一些公有方法来注册监听和分发消息。

/** * Flux的Dispatcher模块 * Created by ntop on 18/12/15. */public classDispatcher{ private static Dispatcher instance; private final List<Store> stores=newArrayList<>(); public static Dispatcher get(){if(instance==null){ instance=newDispatcher();}return instance;}Dispatcher(){} public voidregister(final Store store){ stores.add(store);} public voidunregister(final Store store){ stores.remove(store);} public voiddispatch(Action action){post(action);} private voidpost(final Action action){for(Store store: stores){ store.onAction(action);}}}

Dispatcher对外仅暴露3个公有方法:

  1. register(final Store store) 用来注册每个Store的回调接口
  2. unregister(final Store store) 用来接触Store的回调接口
  3. dispatch(Action action) 用来触发Store注册的回调接口

这里仅仅用一个ArrayList来管理Stores,对于一个更复杂的App可能需要精心设计数据结构来管理Stores组织和相互间的依赖关系。

创建Stores 

这里使用EventBus来实现Store,EventBus的主要功能是用来给Controller-View发送change事件:

/** * Flux的Store模块 * Created by ntop on 18/12/15. */public abstract classStore{ private static final Bus bus=newBus(); protected Store(){} public voidregister(final Object view){this.bus.register(view);} public voidunregister(final Object view){this.bus.unregister(view);} voidemitStoreChange(){this.bus.post(changeEvent());} public abstract StoreChangeEventchangeEvent(); public abstract void onAction(Action action); public class StoreChangeEvent {}}

抽象的Store类,提供了一个主要的虚方法 void onAction(Action action) ,这个方法是注册在Dispatcher里面的回调接口,当Dispatcher有数据派发过来的时候,可以在这里处理。

下面看一下更具体的和业务相关的MessageStore类:

/** * MessageStore类主要用来维护MainActivity的UI状态 * Created by ntop on 18/12/15. */public classMessageStore extendsStore{ private static MessageStore singleton; private Message mMessage=newMessage(); public MessageStore(){super();} public StringgetMessage(){return mMessage.getMessage();} @Override @Subscribe public voidonAction(Action action){ switch(action.getType()){ case MessageAction.ACTION_NEW_MESSAGE: mMessage.setMessage((String) action.getData());break; default:}emitStoreChange();} @Override public StoreChangeEventchangeEvent(){returnnewStoreChangeEvent();}}

在这里实现了 onAction(Action action) 方法,并用一个switch语句来路由各种不同的Action类型。同时维护了一个结构 Message.java 类,这个类用来记录当前要显示的消息。Store类只能通过Dispatcher来更新(不要提供setter方法),对外仅暴露各种getter方法来获取UI状态。这里用String getMessage()方法来获取具体的消息。

在Controller-View里面处理“change”事件 

在Android中,Flux的Controller-View对应于Activity或者Fragment,我们需要在这里注册Strore发生改变的事件通知,以便在Store变化的时候重新绘制UI。

/** * Flux的Controller-View模块 * Created by ntop on 18/12/15. */public classMainActivity extendsAppCompatActivity implementsView.OnClickListener{ private EditText vMessageEditor; private Button vMessageButton; private TextView vMessageView; private Dispatcher dispatcher; private ActionsCreator actionsCreator; private MessageStore store; @Override protected voidonCreate(Bundle savedInstanceState){ super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);initDependencies();setupView();} @Override protected voidonDestroy(){ super.onDestroy(); dispatcher.unregister(store);} private voidinitDependencies(){ dispatcher= Dispatcher.get(); actionsCreator = ActionsCreator.get(dispatcher); store = new MessageStore(); dispatcher.register(store);} private voidsetupView(){ vMessageEditor=(EditText)findViewById(R.id.message_editor); vMessageView = (TextView)findViewById(R.id.message_view); vMessageButton = (Button)findViewById(R.id.message_button); vMessageButton.setOnClickListener(this);} @Override public voidonClick(View view){ int id= view.getId();if(id== R.id.message_button){if(vMessageEditor.getText()!=null){ actionsCreator.sendMessage(vMessageEditor.getText().toString()); vMessageEditor.setText(null);}}} private voidrender(MessageStore store){ vMessageView.setText(store.getMessage());} @Override protected voidonResume(){ super.onResume(); store.register(this);} @Override protected voidonPause(){ super.onPause(); store.unregister(this);} @Subscribe public voidonStoreChange(Store.StoreChangeEvent event){render(store);}}

这部分的代码比较多,首先在 onCreatre(...) 方法中初始化了依赖和需要的UI组件。最重要的是 onStoreChange(...) 方法,这个方法是注册在Store中回调(使用EventBus的@Subscribe注解标识),当Store发生变化的时候会触发这个方法,我们在这里调用render()方法重绘整个界面。

创建Action 

Action是简单的POJO类型,只提供两个字段:type 和 data, 分别记录Action的类型和数据。注意Action一旦创建是不可更改的, 所以它的字段类型修饰为final类型。

public class Action<T>{ private final String type; private final T data;Action(String type, T data){this.type= type;this.data= data;} public StringgetType(){return type;} public TgetData(){return data;}}

下面是一个业务相关的Action实现:

public class MessageAction extends Action<String>{ public static final String ACTION_NEW_MESSAGE="new_message";MessageAction(String type, String data){super(type, data);}}

这个实现非常简单,仅仅多定义了一个Action类型字段:public static final String ACTION_NEW_MESSAGE = "new_message"。如你所见,Action都是这么简单的,不包含任何业务逻辑。

创建ActionCreator 

ActionCreator 是Flux架构中第“四”个最重要的模块(前三:Dispatcher、Store、View),这里实际上处理很多工作,提供有一个有语义的API,构建Action,处理网络请求等。

/** * Flux的ActionCreator模块 * Created by ntop on 18/12/15. */public classActionsCreator{ private static ActionsCreator instance; final Dispatcher dispatcher;ActionsCreator(Dispatcher dispatcher){this.dispatcher= dispatcher;} public static ActionsCreatorget(Dispatcher dispatcher){if(instance==null){ instance=newActionsCreator(dispatcher);}return instance;} public voidsendMessage(String message){ dispatcher.dispatch(newMessageAction(MessageAction.ACTION_NEW_MESSAGE, message));}}

此处提供了一个 sendMessage(String message) ,就像名字暗示的那样,这个方法用来发送消息(到Store)。在方法内部,会创建一个MessageAction来封装数据和Action类型,并通过Dispatcher发送到Store。

Model 

无论是基于哪种框架的应用都需要Model模块,在这个简单的“HelloWorld”应用中,其实用一个String即可传递消息,但是为了架构的完整和更好的语义表达,定义一个Message类型封装一个String字段作为Model。

希望通过这个简单的HelloWorld应用,能够让你一窥Flux的面貌。

转载地址:http://androidflux.github.io/docs/helloworld.html#content

0 0