Android模塊化中數(shù)據(jù)傳遞/路由跳轉(zhuǎn)實(shí)現(xiàn)示例
雖然說(shuō)模塊通信、路由協(xié)議在Android已經(jīng)不新鮮了,但是如果脫離了那些優(yōu)秀的開源庫(kù)我們從零開始自己造一個(gè)庫(kù),有時(shí)候重復(fù)造輪子會(huì)讓自己對(duì)所謂"車"的原理懂得更透徹。
直接上造完的輪子地址: https://github.com/Neacy/NeacyComponent
這個(gè)輪子有兩個(gè)大功能分別是模塊通信以及路由跳轉(zhuǎn):
模塊通信
首先,統(tǒng)一聲明姿勢(shì):
public interface IComponent {
String getName();
void startComponent(ComponentParam param);
}
也就是說(shuō),在各自的維護(hù)的模塊內(nèi)若想提供一個(gè)類供別的模塊調(diào)用那么需要實(shí)現(xiàn)這個(gè) IComponent 類,這樣子可以根據(jù)面向?qū)ο蟮膬?yōu)勢(shì)統(tǒng)一管理,所以我們就有了接下來(lái)的這么一個(gè)個(gè)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", "我來(lái)自AppComponent");
ComponentParam cp = new ComponentParam(results);
callBack.onComponentBack(cp);
}
}
}
兩個(gè)地方比較重要:
- NeacyComponent 這個(gè)注釋,主要是為后面的gradle掃描使用
- getName() 這個(gè)方法返回每個(gè) IComponent 對(duì)應(yīng)的實(shí)例key值,方便在不同的模塊我們可以根據(jù)這個(gè)key值找到對(duì)應(yīng)的 IComponent 對(duì)象
其次,如何調(diào)用呢?
ComponentController.getComponentByName("app").startComponent(null);
是的,只要根據(jù)app這個(gè)key值我們就能輕易的找到對(duì)應(yīng)的 IComponent 對(duì)象,從而執(zhí)行 startComponent ,這個(gè)方法就是你想要在該模塊做的邏輯地方。
看上面我們聲明的 AppComponent 類,我們?cè)?startComponent 有判斷一下傳入的參數(shù)是否為空,這里直接放了一個(gè)偽 Map 類專門用于存放傳遞的參數(shù)。
如何回調(diào)結(jié)果以及如何獲取別的模塊的回調(diào)結(jié)果?
首先你執(zhí)行了別的模塊的 startComponent 方法,在這個(gè)方法中你返回的類肯定只有對(duì)應(yīng)的模塊能識(shí)別,也就是說(shuō)你在自己模塊獲取不到別的模塊中的類,所以這里使用 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", "我來(lái)自AppComponent");
ComponentParam cp = new ComponentParam(results);
callBack.onComponentBack(cp);
// 調(diào)用的時(shí)候傳入?yún)?shù)即可
ComponentController.getComponentByName("app").startComponent(cp);
路由跳轉(zhuǎn)
首先,老規(guī)矩肯定也是聲明一下路由協(xié)議(這里只是一個(gè)簡(jiǎn)單的字符串)
@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掃描注解并在編譯的時(shí)候注入代碼,我們先看下注入成功后的代碼結(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
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
Android 系統(tǒng)net和wap接入點(diǎn)的區(qū)別
這篇文章主要介紹了Android 系統(tǒng)net和wap接入點(diǎn)的區(qū)別的相關(guān)資料,需要的朋友可以參考下2016-09-09
Android序列化接口Parcelable與Serializable接口對(duì)比
我們使用 Intent 傳遞數(shù)據(jù)的時(shí)候,putExtra() 所支持的數(shù)據(jù)類型事有限的,當(dāng)需要傳遞自定義對(duì)象的時(shí)候就需要序列化。Serializable更簡(jiǎn)單但是會(huì)把整個(gè)對(duì)象進(jìn)行序列化因此效率比Parcelable低一些2023-02-02
Flutter獲取ListView當(dāng)前正在顯示的Widget信息(應(yīng)用場(chǎng)景)
ListView是Flutter里最常用的Widget了,當(dāng)屏幕放不下的時(shí)候,它可以自帶滾動(dòng)功能,用法也很簡(jiǎn)單,本文通過實(shí)例代碼給大家介紹Flutter獲取ListView當(dāng)前正在顯示的Widget信息,感興趣的朋友一起看看吧2022-05-05
Android代碼檢查規(guī)則Lint的自定義與應(yīng)用詳解
本文主要介紹了Android代碼檢查規(guī)則Lint的自定義與應(yīng)用詳解,文中通過示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-04-04
Android 通過ViewHolder優(yōu)化適配器的實(shí)現(xiàn)方法(必看)
下面小編就為大家?guī)?lái)一篇Android 通過ViewHolder優(yōu)化適配器的實(shí)現(xiàn)方法(必看)。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來(lái)看看吧2017-04-04
Android開發(fā)筆記之Intent初級(jí)學(xué)習(xí)教程
這篇文章主要介紹了Android開發(fā)筆記之Intent初級(jí)學(xué)習(xí),較為詳細(xì)的分析了Android Intent項(xiàng)目的建立,功能實(shí)現(xiàn)及Intent使用技巧,需要的朋友可以參考下2016-02-02
Android實(shí)現(xiàn)短信驗(yàn)證碼輸入框
這篇文章主要為大家詳細(xì)介紹了Android實(shí)現(xiàn)短信驗(yàn)證碼輸入框,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-11-11

