一.基本介紹
1. 借此機(jī)會(huì)分享一下自己從剛?cè)腴T到現(xiàn)在惭笑,在開發(fā)架構(gòu)方面的一些心路歷程。最終我會(huì)把這部分代碼進(jìn)行開源昼弟,以后也會(huì)對(duì)其進(jìn)行維護(hù)蕾殴。但目前尚在測(cè)試中所以并未發(fā)布正式版本。我們可以先把代碼下載下來進(jìn)行了解黄伊,如果有什么問題可以隨時(shí) Issues泪酱,這也將是我的第一個(gè)開源庫(kù),希望能幫到大家还最。
2. 該庫(kù)所涉及到的類大概在 30 個(gè)左右墓阀,源碼并不多相信我們都能讀懂里面的內(nèi)容,這里羅列一下源碼中所涉及到的一些知識(shí)點(diǎn):
(1) 編譯時(shí)注解自動(dòng)生成 Module拓轻、Action 和 Intercepter
(2) 線程斯撮、線程池、線程同步異步和 Handler
(3) 責(zé)任鏈模式扶叉、享元模式勿锅、策略模式、模板模式 ...
3. 作為一個(gè)多模塊的路由通信庫(kù)枣氧,相信它已支持了所有跨模塊通信的使用場(chǎng)景溢十,功能介紹如下:
(1) 支持依賴注入,可單獨(dú)作為依賴注入框架使用
(2) 支持線程切換和調(diào)度(原始線程达吞,主線程茶宵,同步,異步)
(3) 支持多模塊工程下的所有跨模塊通信使用場(chǎng)景
(4) 支持添加多個(gè)攔截器宗挥,可根據(jù)優(yōu)先級(jí)自定義攔截順序
(5) 支持權(quán)限和網(wǎng)絡(luò)檢測(cè)乌庶、登錄攔截跳轉(zhuǎn)和數(shù)據(jù)埋點(diǎn)等功能
4. 筆者閱讀了大量的開源庫(kù)源碼,本庫(kù)的所有代碼思想都來自其中契耿,很感激這些大牛的開源和分享精神:
(1) ARouter
(2) butterknife
(3) okhttp
(4) EventBus
(5) RxJava
(6) retrofit
二.架構(gòu)的演變之路
首先分享一下自己從剛?cè)腴T到現(xiàn)在瞒大,在開發(fā)架構(gòu)方面的一些心路歷程,從剛開始踏上程序這條不歸路(人生就是一條不歸路)搪桂,想想已經(jīng)是好幾個(gè)年頭透敌,中間經(jīng)歷過提升盯滚、迷茫和進(jìn)階,也經(jīng)歷過從不自信到自信酗电、自滿到自負(fù)魄藕。剛開始一個(gè)人在小公司小打小鬧,是這個(gè)樣子的:
那個(gè)時(shí)候所有的類都是寫在一個(gè)包下面的撵术,所有的 Activity 都是繼承自系統(tǒng)下的 android.app.Activity背率,網(wǎng)絡(luò)框架都是直接用的 android-async-http 所以加班挺嚴(yán)重, 一方面是自己能力經(jīng)驗(yàn)還不夠嫩与,另一方面是沒有架構(gòu)的情況下很多代碼都是反復(fù)冗余的寝姿。畢業(yè)后去了一家上市公司,多人團(tuán)隊(duì)協(xié)作開發(fā)所以就改變了一些:
這個(gè)時(shí)候已經(jīng)有所提升了划滋,所有的 Activity 也不是直接繼承自 android.app.Activity 了饵筑,也不再是直接使用 android-async-http 所以開發(fā)的日子自然舒坦了一些。一方面是經(jīng)驗(yàn)?zāi)芰ι先チ擞龅絾栴}能馬上解決处坪,另一方面基于架構(gòu)開發(fā)很多代碼不用反復(fù)寫后期也便于維護(hù)根资,最主要的是大公司人多一些,之前是一個(gè)人干四個(gè)人的活同窘,現(xiàn)在四個(gè)人干一個(gè)人的活嫂冻。隨著開發(fā)人員的越來越多,還有就是基本每逢過節(jié)都要做一些活動(dòng)塞椎,等活動(dòng)過后這些代碼和資源就要?jiǎng)h除桨仿,而且每?jī)蓚€(gè)月就得迭代一個(gè)新的版本,所以變得越來越復(fù)雜起來案狠。后來就衍生出了很多像熱更新服傍、插件化、多模塊多組件開發(fā)等等骂铁。當(dāng)然剛開始的多模塊多組件并未基于路由吹零,是蜘蛛網(wǎng)的狀態(tài)。
會(huì)有這么亂嗎拉庵?隨著業(yè)務(wù)邏輯更加復(fù)雜的情況下應(yīng)該會(huì)更亂灿椅,因?yàn)楣δ苣K都是各自存在于自己的 Module 中,但是可能在開發(fā)的過程中 Module1 得調(diào)用 Module2 的代碼钞支,這個(gè)時(shí)候如果是直接添加依賴那么肯定就會(huì)有這么亂了茫蛹。接下來看下基于路由情況下的多模塊多組件開發(fā):
三. DRouter 基本使用
- 在需要跨模塊通信的Module中添加依賴和配置
defaultConfig {
......
javaCompileOptions {
annotationProcessorOptions {
arguments = [moduleName: project.getName()]
}
}
}
dependencies {
.......
annotationProcessor project(':drouter-compiler')
}
- 在 Module 中創(chuàng)建需要執(zhí)行的 Action
// path 必須是以在 gradle 中配置的 moduleName + "/" 開頭,否則編譯通不過烁挟。
// threadMode 支持 POSTING 婴洼、MAIN、BACKGROUND撼嗓、ASYNC 默認(rèn)情況下是 POSTING(原始線程)
@Action(path = "login/action", threadMode = ThreadMode.MAIN)
public class LoginAction implements IRouterAction {
@Override
public RouterResult invokeAction(Context context, Map<String, Object> requestData) {
// 通信執(zhí)行方法支持所有場(chǎng)景柬采,啟動(dòng) Activity欢唾,Service,Provider粉捻,彈框礁遣,緩存數(shù)據(jù),獲取 Fragment 等等等等
Intent intent = new Intent(context, LoginActivity.class);
intent.putExtra("key", (String) requestData.get("key"));
context.startActivity(intent);
return new RouterResult.Builder().success().object(100).build();
}
}
- 初始化 SDK
public class BaseApplication extends Application{
@Override
public void onCreate() {
super.onCreate();
// 開啟 debug
DRouter.openDebug();
// 初始化且只能初始化一次肩刃,參數(shù)必須是 Application
DRouter.getInstance().init(this);
}
}
- 可在任意 Module 中執(zhí)行跳轉(zhuǎn)
// 根據(jù) action 查詢只執(zhí)行對(duì)應(yīng)方法祟霍,不處理返回回調(diào),參數(shù)攜帶隨意
DRouter.getInstance()
.action("login/action")
.context(this)
.param("key", "value")
.invokeAction();
// 根據(jù) action 查詢執(zhí)行對(duì)應(yīng)方法树酪,并處理返回回調(diào)
DRouter.getInstance()
.action("circlemodule/test")
.context(this)
.invokeAction(new ActionCallback() {
@Override
public void onInterrupt() {
Log.e("TAG", "被攔截了");
}
@Override
public void onResult(RouterResult result) {
// 注意該方法的執(zhí)行線程是由 Action 的 threadMode 決定的浅碾,也就是說和 Action 在同一個(gè)線程
Log.e("TAG", "result = " + result.toString());
}
});
- 在任意模塊下都可添加攔截
// priority 優(yōu)先級(jí)越高大州,攔截器執(zhí)行越優(yōu)先
@Interceptor(priority = 18)
public class CircleInterceptor implements ActionInterceptor {
@Override
public void intercept(ActionChain chain) {
ActionPost actionPost = chain.action();
// 圈子詳情頁必須是要登錄续语,如果沒有登錄即可攔截跳轉(zhuǎn)到登錄頁面,否則繼續(xù)往下執(zhí)行厦画。
if (chain.actionPath().equals("circlemodule/test")) {
Toast.makeText(actionPost.context, "攔截圈子疮茄,跳轉(zhuǎn)到登錄", Toast.LENGTH_LONG).show();
// 跳轉(zhuǎn)到登錄頁面
DRouter.getInstance()
.action("login/action")
.context(actionPost.context)
.invokeAction();
// 這個(gè)方法調(diào)用后便會(huì)攔截整條鏈
chain.onInterrupt();
}
// 繼續(xù)向下轉(zhuǎn)發(fā)
chain.proceed(actionPost);
}
}
6.混淆配置
-keep public class com.drouter.assist.**{*;}
源碼地址:https://github.com/HCDarren/DRouter
視頻講解:https://pan.baidu.com/s/1kWoIA95