Android开发之Flux架构
什么是Flux?
Flux是一种软件开发架构,开发流程遵循Restful的点对点的数据流向,降低代码之间的耦合性,使得代码之间的调用更加清晰,Flux开始是应用于前端的技术架构,只要解决前端中资源与调用者的唯一性,下面是Flux架构的核心思想:
View
view是代表展示给用户的界面,比如Activity或者Fragment。
Action
Action表示一种行为的数据封装(可能感觉抽象咬咬牙看完就懂了),每个Avtion中包含行为的Type以及行为的数据Data
Store
Store用来跟新View层的数据,根据dispatcher分发给的Action去将数据通知到View
Dispatcher
顾名思义就是Action的分发器,负责将Action分发到Store中。
代码详解
- 创建Action的基类,内部包含两个成员变量,Action是用来由Dispatcher分发到Store的数据封装
public abstract class BaseAction<T> {
protected String eventType; // 事件类型
protected T data; // 处理的数据
public BaseAction(String type,T data){
this.eventType = type;
this.data = data;
}
public BaseAction(String type){
this.eventType = type;
}
public String getEventType() {
return eventType;
}
public void setEventType(String eventType) {
this.eventType = eventType;
}
public T getData() {
return data;
}
public void setData(T data) {
this.data = data;
}
}
- 创建Store基类,内部创建用来将Action中携带的数据通过Otto或者EventBus来通知到注册到了异步通信框架的View
public abstract class BaseStore {
private static final Bus bus = new Bus();
// 将View层注册进Otto
public void regist(Object view){
bus.register(view);
}
// 将View层从Otto中注销
public void unRegist(Object view){
bus.unregister(view);
}
// 将Action消息中的数据转换成ChangeStore对象发送出去
public void emitStoreChange(String type,String msg){
bus.post(new ChangeStore(type,msg));
}
public void emitStoreChange(String type){
bus.post(new ChangeStore(type));
}
// 子类根据action的类型进行数据发射或者封装
protected abstract void onAction(BaseAction action);
/* 创建一个Otto进行消息通知的承载类
* */
public class ChangeStore{
private String type;
private String msg;
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public String getMsg() {
return msg;
}
public void setMsg(String msg) {
this.msg = msg;
}
public ChangeStore(String type, String msg) {
this.type = type;
this.msg = msg;
}
public ChangeStore(String type) {
this.type = type;
}
}
}
- Dispatcher内部维护了一个Store的集合,dispatcher发送Action消息时遍历所有的Store,调用Store的onAction方法,在Store的子类中根据传递的Action中的类型和数据调用Store的emitStoreChange方法。
public class Dispatcher {
private static final List<BaseStore> stores = new ArrayList<>(); // 储存所有交由Dispatcher管理的store
private Dispatcher(){}
private static Dispatcher dispatcher ;
public static Dispatcher getInstance(){
if(dispatcher==null){
synchronized (Dispatcher.class){
if(dispatcher==null){
dispatcher = new Dispatcher();
}
}
}
return dispatcher;
}
// store 注册给dispatcher
public void regist(BaseStore store){
stores.add(store);
}
// 注销store从dispatcher
public void unRegist(BaseStore store){
stores.remove(store);
}
// 接受view中触发的action 遍历所有store 将事件发送给注册了该store的view层
public void post(BaseAction action ){
for (BaseStore s : stores) {
s.onAction(action);
}
}
}
- AppActionCreator用来供View层调用,内部包含一个Dispatcher的实例,用来发送相应的Action。
public class AppActionCreator {
private static Dispatcher dispatcher = Dispatcher.getInstance();
private AppActionCreator(){}
private static AppActionCreator appActionCreator = null;
public static AppActionCreator getInstance(){
if(appActionCreator==null){
synchronized (AppActionCreator.class){
if(appActionCreator==null){
appActionCreator = new AppActionCreator();
}
}
}
return appActionCreator;
}
public void login(){
dispatcher.post(new LoginAction(LoginAction.LOGIN_START,"登录中"));
// 模拟网络请求
if(System.currentTimeMillis()/2==0){
dispatcher.post(new LoginAction(LoginAction.LOGIN_SUCCESS,"登录成功"));
}else{
dispatcher.post(new LoginAction(LoginAction.LOGIN_FAIL,"登陆失败"));
}
}
}
- View层负责创建一个该View对应的Store,将该View注册到Store,从而注册到Otto,将该Store注册到Dispatcher中,方便Dispatcher遍历Store发送onAction事件
public class MainActivity extends AppCompatActivity {
private LoginStore loginStore;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
loginStore = new LoginStore();
loginStore.regist(this);
Dispatcher.getInstance().regist(loginStore);
}
// 登录
public void login(View v) {
AppActionCreator.getInstance().login();
}
@Override
protected void onStop() {
super.onStop();
loginStore.unRegist(this);
}
@Override
protected void onDestroy() {
super.onDestroy();
Dispatcher.getInstance().unRegist(loginStore);
}
// Otto的回调监听
@Subscribe
public void LoginListener(BaseStore.ChangeStore changEvent) {
String type = changEvent.getType();
String msg = changEvent.getMsg();
Toast.makeText(this, type+msg, Toast.LENGTH_SHORT).show();
}
}
接下来就是具体的编写Store和Action:
LoginStore:
public class LoginAction extends BaseAction<String> {
public static final String LOGIN_START = "login_start";
public static final String LOGIN_SUCCESS = "login_success";
public static final String LOGIN_FAIL = "login_fail";
public LoginAction(String type, String data) {
super(type, data);
}
public LoginAction(String type) {
super(type);
}
}
LoginStore
public class LoginStore extends BaseStore {
@Override
protected void onAction(BaseAction action) {
String type = action.getEventType();
switch (type){
case LoginAction.LOGIN_START:
emitStoreChange(type,(String) action.getData());
break;
case LoginAction.LOGIN_SUCCESS:
emitStoreChange(type,(String) action.getData());
break;
case LoginAction.LOGIN_FAIL:
emitStoreChange(type,(String) action.getData());
break;
}
}
}
总结:
Flux结构是遵循采用数据单项流转,我们要实现在activity(view)中的操作处理,并响应操作进行ui更新,都要实现activity所对应的Action,Store,而且都是一一对应的关系。这样虽然编写的代码量可能增加,但是流程更加清晰,各个层解耦程度高,方便调试。