Android學習之Flux架構入門_Android

來源:互聯網
上載者:User

Flux 架構介紹

Flux 架構 被Facebook使用來構建他們的用戶端web應用。跟Clean Architecture一樣,它不是為行動裝置 App設計的,但是它的特性和簡單可以讓我們很好的在安卓項目中採用。

Flux模式最大的特點是單向的資料流,它的UI狀態更新模式繼承了MVC模式的設計思想。Flux並不是具體的架構,而是一套處理UI問題的模式,Android Flux同樣不是具體的架構,你不需要匯入或者整合任何新的代碼就可以使用,而你需要做的事情是瞭解這套思想、遵循這種開發模式,查看我們提供的Android程式碼範例,寫自己的代碼。

要理解Flux,有兩個關鍵的特點

1、資料流總是單向的

      一個單向的資料流 是 Flux 架構的核心,也是它簡單易學的原因。就如下面討論的,在進行應用測試的時候,它提供了非常大的協助。

2、應用被分成三個主要部分:

     . View: 應用的介面。這裡建立響應使用者操作的action

     . Dispatcher: 中心樞紐,傳遞所有的action,負責把它們運達每個Store

     . Store: 維護一個特定application domain的狀態。它們根據目前狀態響應action,執行商務邏輯,同時在完成的時候發出一個change事件。這個事件用於view更新其介面。

     這三個部分都是通過Action來通訊的:一個簡單的基本對象,以類型來區分,包含了和操作相關的資料。

Flux Android 架構

在安卓開發中使用Flux設計規範的目的是建立一個在簡單性與易擴充易測試之間都比較平衡的架構。

第一步是找到Flux元素和安卓app組件之間的映射。

其中兩個元素非常容易找到與實現。

View: Activity o或者Fragment

Dispatcher: 一個事件匯流排( event bus),在我的例子中將使用Otto,但是其它任何實現都應該是ok的。

Actions

Actions也不複雜。它們的實現和POJO一樣簡單,有兩個主要屬性:

     1、Type: 一個String,定義了事件的類型。

     2、Data: 一個map,裝載了本次操作。

Store是Flux理論中最難的部分。

Stores響應Dispatcher發出的Action,執行商務邏輯並發送change事件。Stores的唯一輸出是這單一的事件:change。其它對Store內部狀態感興趣的組件必須監聽這個事件,同時使用它擷取需要的資料。最後,stores必須對外公開一個擷取application狀態的介面。這樣,view元素可以查詢Stores然後相應的更新UI。

這裡通過一個簡單的小demo來講述整個流程。我們的介面上有一個Button和一個TextView,點擊Button後讓TextView顯示出文字。常規的實現,直接在Activity中完成邏輯,MVP模式,在Presenter層來進行,對於Flux架構,我們要怎麼實現呢。通過上圖我們可以看到,View會產生Action,然後被Dispatcher進行調度,經過Store相應處理,將資料顯示出來。

如何產生Action

首先要知道Action是什麼樣

public class Action {  private final String type;  private final HashMap<String, Object> data;  public Action(String type, HashMap<String, Object> data) {    this.type = type;    this.data = data;  }  public static Builder type(String type) {    return new Builder().with(type);  }  public String getType() {    return type;  }  public HashMap getData() {    return data;  }  public static class Builder {    private String type;    private HashMap<String, Object> data;    Builder with(String type) {      if(type == null) {        throw new IllegalArgumentException("Type may not be null.");      }      this.type = type;      this.data = new HashMap<>();      return this;    }    public Builder bundle(String key, Object value) {      if (key == null) {        throw new IllegalArgumentException("Key may not be null.");      }      if(value == null) {        throw new IllegalArgumentException("Value may not be null.");      }      data.put(key, value);      return this;    }    public Action build() {      if (TextUtils.isEmpty(type)) {        throw new IllegalArgumentException("At least one key is required.");      }      return new Action(type, data);    }  }}

每一個Action有兩個屬性,一個來標記Type,另一個欄位來儲存傳送的資料,通過Map來存放。

對於Action Type,我們可以通過一個介面或者類來進行記錄,將所有的類型儲存在其中。方便我們的調用。

public interface ShowActions {  String TODO_SHOW = "todo-show";  String GET_TEXT = "get-text";}

如何建立Action,定義一個類,專門用來根據我們可能會出現的各種View的事件,定義出來各種Action

public class ActionsCreator {  private static ActionsCreator instance;  final Dispatcher mDispatcher;  ActionsCreator(Dispatcher dispatcher){    mDispatcher = dispatcher;  }  public static ActionsCreator get(Dispatcher dispatcher) {    if (instance == null) {      instance = new ActionsCreator(dispatcher);    }    return instance;  }  public void create(String text) {    mDispatcher.dispatch(ShowActions.TODO_SHOW, ShowActions.GET_TEXT, text);  }

在我們準備用ActionsCreator來建立Action的時候,我們並沒有直接new Action這種方式來做,而是將其通過調度器,對其進行了分發。這裡的事件分發,我們使用的是OttoBus來進行事件的分發。

public class Dispatcher {  private final Bus bus;  private static Dispatcher instance;  Dispatcher(Bus bus){    this.bus = bus;  }  public static Dispatcher get(Bus bus) {    if (instance == null) {      instance = new Dispatcher(bus);    }    return instance;  }  public void register(final Object cls) {    bus.register(cls);  }  public void unRegister(final Object cls) {    bus.unregister(cls);  }  public void emitChange(Store.StoreChangeEvent o) {post(o);}  public void dispatch(String type, Object... data) {    if(TextUtils.isEmpty(type)) {      throw new IllegalArgumentException("Type must not be empty");    }    if (data.length % 2 != 0) {      throw new IllegalArgumentException("Data must be a valid list of key");    }    Action.Builder actionBuilder = Action.type(type);    for (int i = 0; i < data.length; i++) {      String key = (String) data[i++];      Object value = data[i++];      actionBuilder.bundle(key, value);    }    post(actionBuilder.build());  }  private boolean isEmpty(String type) {    return TextUtils.isEmpty(type);  }  private void post(final Object event) {    bus.post(event);  }}

在調度的過程中,我們將傳遞進來的資料進行一個解析,然後根據資料建立出相應的Action,然後對Action進行分發,這個時候關注了相應的ActionStore就會開始根據相應的Action開始執行相應的操作。在Store中,聲明了一個抽象方法onAction來負責進行對於Action的判斷和分發,然後定義了StoreChangeEvent介面作為事件變化,當有變化的時候,通過這個進行傳遞,我們可以自己實現這個介面,然後在裡面添加一些方法和欄位用來攜帶資料。

public abstract class Store {  final Dispatcher mDispatcher;  protected Store(Dispatcher dispatcher) {    this.mDispatcher = dispatcher;  }  void emitStoreChange() {    mDispatcher.emitChange(changeEvent());  }  abstract StoreChangeEvent changeEvent();  public abstract void onAction(Action action);  public interface StoreChangeEvent {}}

我們自訂的Store類

public class ShowStore extends Store {  private static ShowStore instance;  private String showText;  public ShowStore(Dispatcher dispatcher){    super(dispatcher);  }  public static ShowStore get(Dispatcher dispatcher) {    if (instance == null) {      instance = new ShowStore(dispatcher);    }    return instance;  }  @Subscribe  public void onAction(Action action) {    switch (action.getType()) {      case ShowActions.TODO_SHOW :        showText = ((String)action.getData().get(ShowActions.GET_TEXT));        Log.i("showText", showText);        emitStoreChange();        break;      default:        break;    }  }  public String getShowText(){    return showText;  }  @Override  StoreChangeEvent changeEvent() {    return new ShowChangeEvent();  }  public class ShowChangeEvent implements StoreChangeEvent {  }}

然後我們在View也就是Activity中訂閱了變化時間的方法,這個時候就可以實現對於View中的資料的一個動態更新。

 @Subscribe  public void showText (ShowStore.ShowChangeEvent event){    mTextView.setText(mShowStore.getShowText());   }

總結

通過Flux架構,使用的流程是,我們的View的事件會攜帶資料,通過一個ActionsCreate建立一個Type的Action,實際完成過程是在Dispatcher的dispatch中,然後再將這個Action丟給訂閱了該Action的Store方法中,在這裡完成各種邏輯,處理,甚至是可以發起網路請求擷取資料,處理完成,可以將結果封裝成一個事件,然後這個事件會再次通過調度器中的emitChangeEvent將事件傳遞給訂閱了該事件的函數,而這個接收響應事件的函數被我們定義在我們View中,從而實現對於我們View的更新。以上就是本文的全部內容了,希望本文的內容對大家學習Flux架構有所協助。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.