Android 多模塊多組件開發(fā) - 打造屬于自己的路由

一.基本介紹

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 基本使用

  1. 在需要跨模塊通信的Module中添加依賴和配置
    defaultConfig {
        ......
        javaCompileOptions {
            annotationProcessorOptions {
                arguments = [moduleName: project.getName()]
            }
        }
    }

    dependencies {
        .......
        annotationProcessor project(':drouter-compiler')
    }
  1. 在 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();
    }
}
  1. 初始化 SDK
public class BaseApplication extends Application{
    @Override
    public void onCreate() {
        super.onCreate();
        // 開啟 debug
        DRouter.openDebug();
        // 初始化且只能初始化一次肩刃,參數(shù)必須是 Application
        DRouter.getInstance().init(this);
    }
}
  1. 可在任意 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());
                    }
                });
  1. 在任意模塊下都可添加攔截
// 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

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市根暑,隨后出現(xiàn)的幾起案子力试,更是在濱河造成了極大的恐慌,老刑警劉巖排嫌,帶你破解...
    沈念sama閱讀 218,941評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件畸裳,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡淳地,警方通過查閱死者的電腦和手機(jī)怖糊,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,397評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來颇象,“玉大人伍伤,你說我怎么就攤上這事∏睬” “怎么了扰魂?”我有些...
    開封第一講書人閱讀 165,345評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)蕴茴。 經(jīng)常有香客問我劝评,道長(zhǎng),這世上最難降的妖魔是什么倦淀? 我笑而不...
    開封第一講書人閱讀 58,851評(píng)論 1 295
  • 正文 為了忘掉前任付翁,我火速辦了婚禮,結(jié)果婚禮上晃听,老公的妹妹穿的比我還像新娘百侧。我一直安慰自己砰识,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,868評(píng)論 6 392
  • 文/花漫 我一把揭開白布佣渴。 她就那樣靜靜地躺著辫狼,像睡著了一般。 火紅的嫁衣襯著肌膚如雪辛润。 梳的紋絲不亂的頭發(fā)上膨处,一...
    開封第一講書人閱讀 51,688評(píng)論 1 305
  • 那天,我揣著相機(jī)與錄音砂竖,去河邊找鬼真椿。 笑死,一個(gè)胖子當(dāng)著我的面吹牛乎澄,可吹牛的內(nèi)容都是我干的突硝。 我是一名探鬼主播,決...
    沈念sama閱讀 40,414評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼置济,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼解恰!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起浙于,我...
    開封第一講書人閱讀 39,319評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤护盈,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后羞酗,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體腐宋,經(jīng)...
    沈念sama閱讀 45,775評(píng)論 1 315
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,945評(píng)論 3 336
  • 正文 我和宋清朗相戀三年檀轨,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了胸竞。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,096評(píng)論 1 350
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡裤园,死狀恐怖撤师,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情拧揽,我是刑警寧澤剃盾,帶...
    沈念sama閱讀 35,789評(píng)論 5 346
  • 正文 年R本政府宣布,位于F島的核電站淤袜,受9級(jí)特大地震影響痒谴,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜铡羡,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,437評(píng)論 3 331
  • 文/蒙蒙 一积蔚、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧烦周,春花似錦尽爆、人聲如沸怎顾。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,993評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽槐雾。三九已至,卻和暖如春幅狮,著一層夾襖步出監(jiān)牢的瞬間募强,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,107評(píng)論 1 271
  • 我被黑心中介騙來泰國(guó)打工崇摄, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留擎值,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,308評(píng)論 3 372
  • 正文 我出身青樓逐抑,卻偏偏與公主長(zhǎng)得像鸠儿,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子泵肄,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,037評(píng)論 2 355