Android模塊化中數(shù)據(jù)傳遞/路由跳轉(zhuǎn)實(shí)現(xiàn)示例
雖然說模塊通信、路由協(xié)議在Android已經(jīng)不新鮮了,但是如果脫離了那些優(yōu)秀的開源庫我們從零開始自己造一個庫,有時候重復(fù)造輪子會讓自己對所謂"車"的原理懂得更透徹。
直接上造完的輪子地址: https://github.com/Neacy/NeacyComponent
這個輪子有兩個大功能分別是模塊通信以及路由跳轉(zhuǎn):
模塊通信
首先,統(tǒng)一聲明姿勢:
public interface IComponent { String getName(); void startComponent(ComponentParam param); }
也就是說,在各自的維護(hù)的模塊內(nèi)若想提供一個類供別的模塊調(diào)用那么需要實(shí)現(xiàn)這個 IComponent 類,這樣子可以根據(jù)面向?qū)ο蟮膬?yōu)勢統(tǒng)一管理,所以我們就有了接下來的這么一個個Component類,比如:
@NeacyComponent("app") public class AppComponent implements IComponent { @Override public String getName() { return "app"; } @Override public void startComponent(ComponentParam param) { Log.w("Jayuchou", "==== Start AppComponent ===="); if (param != null && param.getParam().containsKey("callback")) { ICallBack callBack = (ICallBack) param.getParam().get("callback"); Map<String, Object> results = new HashMap<>(); results.put("result", "我來自AppComponent"); ComponentParam cp = new ComponentParam(results); callBack.onComponentBack(cp); } } }
兩個地方比較重要:
- NeacyComponent 這個注釋,主要是為后面的gradle掃描使用
- getName() 這個方法返回每個 IComponent 對應(yīng)的實(shí)例key值,方便在不同的模塊我們可以根據(jù)這個key值找到對應(yīng)的 IComponent 對象
其次,如何調(diào)用呢?
ComponentController.getComponentByName("app").startComponent(null);
是的,只要根據(jù)app這個key值我們就能輕易的找到對應(yīng)的 IComponent 對象,從而執(zhí)行 startComponent ,這個方法就是你想要在該模塊做的邏輯地方。
看上面我們聲明的 AppComponent 類,我們在 startComponent 有判斷一下傳入的參數(shù)是否為空,這里直接放了一個偽 Map 類專門用于存放傳遞的參數(shù)。
如何回調(diào)結(jié)果以及如何獲取別的模塊的回調(diào)結(jié)果?
首先你執(zhí)行了別的模塊的 startComponent 方法,在這個方法中你返回的類肯定只有對應(yīng)的模塊能識別,也就是說你在自己模塊獲取不到別的模塊中的類,所以這里使用 ComponentParam 采用key/value的風(fēng)格存放參數(shù)以及回調(diào)返回結(jié)果,然后看一下下面的代碼就能明白答案了。
// 傳遞參數(shù)給IComponent, 可以通過傳遞回調(diào)函數(shù)從而得到回調(diào)結(jié)果 Map<String, Object> p = new HashMap<>(); p.put("callback", new ICallBack() { @Override public void onComponentBack(ComponentParam result) { Log.w("Jayuchou", "==== 運(yùn)行結(jié)果 = " + result.getParam().get("result")); } }); ComponentParam cp = new ComponentParam(p); // 回調(diào)結(jié)果回去 ICallBack callBack = (ICallBack) param.getParam().get("callback"); Map<String, Object> results = new HashMap<>(); results.put("result", "我來自AppComponent"); ComponentParam cp = new ComponentParam(results); callBack.onComponentBack(cp); // 調(diào)用的時候傳入?yún)?shù)即可 ComponentController.getComponentByName("app").startComponent(cp);
路由跳轉(zhuǎn)
首先,老規(guī)矩肯定也是聲明一下路由協(xié)議(這里只是一個簡單的字符串)
@NeacyProtocol("/activity/a") public class AActivity extends AppCompatActivity @NeacyProtocol("/activity/b") public class BActivity extends AppCompatActivity @NeacyProtocol("/activity/app") public class MainActivity extends AppCompatActivity
然后調(diào)用就是了:
RouterController.startRouter(MainActivity.this, "/activity/a");// 跳轉(zhuǎn)到AActivity Bundle args = new Bundle(); args.putString("key", "AActivity"); RouterController.startRouter(AActivity.this, "/activity/b", args);// 跳轉(zhuǎn)到BActivity并攜帶bundle參數(shù)
原理
原理就是通過gradle插件結(jié)合ASM掃描注解并在編譯的時候注入代碼,我們先看下注入成功后的代碼結(jié)構(gòu):
1.模塊通信的注入結(jié)果
public class ComponentController { static { registerComponent(new AComponent()); registerComponent(new BComponent()); registerComponent(new AppComponent()); } private static Map<String, IComponent> components = new HashMap(); static void registerComponent(IComponent component) { components.put(component.getName(), component); } . . . }
2.路由跳轉(zhuǎn)注入結(jié)果
public class RouterController { static { addRouter("/activity/a", "com.neacy.neacy_a.AActivity"); addRouter("/activity/b", "com.neacy.neacy_b.BActivity"); addRouter("/activity/app", "com.neacy.component.MainActivity"); } private static Map<String, String> routers = new HashMap(); public static void addRouter(String key, String value) { routers.put(key, value); } }
3.更多gradle插件的代碼查閱 https://github.com/Neacy/NeacyComponent
最后
再次感謝靈感: https://github.com/luckybilly/CC
以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
Android MediaPlayer實(shí)現(xiàn)音樂播放器實(shí)例代碼
這篇文章主要介紹了Android MediaPlayer實(shí)現(xiàn)音樂播放器實(shí)例代碼的相關(guān)資料,需要的朋友可以參考下2017-01-01WebView設(shè)置WebViewClient的方法
這篇文章主要介紹了 WebView設(shè)置WebViewClient的方法的相關(guān)資料,希望通過本文能幫助到大家,需要的朋友可以參考下2017-09-09android實(shí)現(xiàn)listview分頁的方法
這篇文章主要介紹了android實(shí)現(xiàn)listview分頁的方法,涉及Android生成listview列表的相關(guān)技巧,需要的朋友可以參考下2015-05-05ViewDragHelper實(shí)現(xiàn)QQ側(cè)滑效果
這篇文章主要為大家詳細(xì)介紹了ViewDragHelper實(shí)現(xiàn)QQ側(cè)滑效果,具有一定的參考價值,感興趣的小伙伴們可以參考一下2017-08-08Android列表實(shí)現(xiàn)單選點(diǎn)擊縮放動畫效果
在android開發(fā),我們會常常使用到縮放動畫,這篇文章主要給大家介紹了關(guān)于Android列表實(shí)現(xiàn)單選點(diǎn)擊縮放動畫效果的相關(guān)資料,需要的朋友可以參考下2021-08-08Android實(shí)現(xiàn)圖片輪播切換實(shí)例代碼
利用Android的ViewFlipper和AnimationUtils實(shí)現(xiàn)圖片帶有動畫的輪播切換,其中當(dāng)點(diǎn)擊“上一張”圖片時,切換到上一張圖片;當(dāng)點(diǎn)擊“下一張”圖片時,切換到下一張圖片,本文給大家介紹Android實(shí)現(xiàn)圖片輪播切換實(shí)例代碼,需要的朋友參考下2015-12-12