Android模塊化路由組件

模塊化是基于BaseLibrary開發(fā),日常開發(fā)是個(gè)app,打包時(shí)是個(gè)Library;這樣便于日常開發(fā)時(shí)編譯快,且可以快速把模塊化放入其它apk扯饶;限制就是只能有主App向各種業(yè)務(wù)模塊Library跳轉(zhuǎn),這也是為什么模塊化的前提详拙,需要在熟悉業(yè)務(wù)的情況模塊化帝际;如果各種頁面之間隨便跳也會(huì)讓模塊化失去意義
本篇需要的知識(shí)點(diǎn)是注解、動(dòng)態(tài)代理 饶辙、隱式跳轉(zhuǎn)等知識(shí)

1蹲诀、首先在BaseLibrary定義跳轉(zhuǎn)的路由注解

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface FullUrl {

    String value();
}

2、在BaseLibrary定義跳轉(zhuǎn)的參數(shù)注解

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.PARAMETER)
public @interface IntentExtrasParam {

    String value();
}

3弃揽、在BaseLibrary定義動(dòng)態(tài)代理

public class Router {

    private Context context;
    private static final String TAG = "Router";

    public Router(Context context) {
        this.context = context;
    }

    @SuppressWarnings("unchecked")
    public <T> T create(Class<T> service){
        return (T) Proxy.newProxyInstance(service.getClassLoader(), new Class[]{service}, new InvocationHandler() {
            @Override
            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                StringBuilder builder = new StringBuilder();
                FullUrl fullUrl = method.getAnnotation(FullUrl.class);
                if(fullUrl instanceof FullUrl){
                    builder.append(fullUrl.value()).append("?");
                }else {
                    throw new IllegalArgumentException("");
                }

                Annotation[][] parameterAnnotations = method.getParameterAnnotations();

                HashMap<String, Object> serializedParams = new HashMap<>();
                for (int i=0;i<parameterAnnotations.length;i++){
                    Annotation[] parameterAnnotation = parameterAnnotations[i];
                    if (parameterAnnotation == null || parameterAnnotation.length == 0)
                        break;

                    Annotation annotation = parameterAnnotation[0];
                    if(annotation instanceof IntentExtrasParam){
                       IntentExtrasParam intentExtrasParam= (IntentExtrasParam) annotation;
                       serializedParams.put(intentExtrasParam.value(),args[i]);
                    }
                }
                performJump(builder.toString(),serializedParams);
                return null;
            }
        });
    }

    private void performJump(String routerUri, HashMap<String, Object> serializedParams) {
        Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(routerUri));

        Log.e(TAG, "performJump: "+ Uri.parse(routerUri));
        Bundle bundle = new Bundle();
        for (Map.Entry<String,Object> entry:serializedParams.entrySet()){
            String key = entry.getKey();
            Object value = entry.getValue();
//可以根據(jù)自己的項(xiàng)目需求自由擴(kuò)展支持?jǐn)?shù)據(jù)類型脯爪,這里只提供了String和Parcelable類型
            if(value instanceof String){
                bundle.putString(key,(String) value);
                Log.e(TAG, "string: "+(String) value);
            }else if(value instanceof Parcelable){
                bundle.putParcelable(key, (Parcelable) value);
                Log.e(TAG, "Parcelable: "+(Parcelable) value);
            }else {
                throw new IllegalArgumentException("不支持的數(shù)據(jù)類型");
            }
        }
        intent.putExtras(bundle);
        Log.e(TAG, "performJump: "+intent);
        PackageManager packageManager = context.getPackageManager();
        List<ResolveInfo> activities = packageManager.queryIntentActivities(intent, 0);
        if (!activities.isEmpty()) {
            context.startActivity(intent);
        }

    }
}

4则北、在業(yè)務(wù)模塊的Library內(nèi)定義接口;需要注意的是,由App模塊跳轉(zhuǎn)到業(yè)務(wù)模塊的頁面定義的路由接口放到業(yè)務(wù)模塊內(nèi)痕慢,這樣便于管理業(yè)務(wù)模塊的路由頁面尚揣,這也是為什么不使用顯示跳轉(zhuǎn)或者隱式跳轉(zhuǎn)的原因,便于管理路由頁面

public interface RouterService {

    @FullUrl("router://com.xiaoma.mylibrary.libraryactivity")
    void startLibraryActivity(@IntentExtrasParam("stringParam") String stringParam,
                              @IntentExtrasParam("user") User user);
}

其中User類如下,其中g(shù)et/set相關(guān)方法和Parcelabel未寫出來

public class User implements Parcelable {

    private String name;
    private int age;
}

5掖举、業(yè)務(wù)模塊路由頁面的清單文件定義如下

 <activity android:name="com.xiaoma.mylibrary.LibraryActivity">
            <intent-filter>
                <category android:name="android.intent.category.DEFAULT" />
                <action android:name="android.intent.action.VIEW" />
                <data
                    android:host="com.xiaoma.mylibrary.libraryactivity"
                    android:scheme="router" />
            </intent-filter>
        </activity>

6快骗、在主App內(nèi),跳轉(zhuǎn)到模塊化頁面代碼

 RouterService routerService = new Router(this).create(RouterService.class);
        User user = new User("張三", 30);
        routerService.startLibraryActivity("xiaoma", user);

7塔次、從主App跳轉(zhuǎn)到模塊化頁面獲取數(shù)據(jù)的代碼如下:

 String stringParam = getIntent().getStringExtra("stringParam");
        User user = getIntent().getParcelableExtra("user");

關(guān)于路由和注解的項(xiàng)目地址

文章參考
Android 模塊化探索與實(shí)踐

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末方篮,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子励负,更是在濱河造成了極大的恐慌藕溅,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,682評(píng)論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件继榆,死亡現(xiàn)場(chǎng)離奇詭異巾表,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)略吨,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,277評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門集币,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人晋南,你說我怎么就攤上這事惠猿「崂” “怎么了负间?”我有些...
    開封第一講書人閱讀 165,083評(píng)論 0 355
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)姜凄。 經(jīng)常有香客問我政溃,道長(zhǎng),這世上最難降的妖魔是什么态秧? 我笑而不...
    開封第一講書人閱讀 58,763評(píng)論 1 295
  • 正文 為了忘掉前任董虱,我火速辦了婚禮,結(jié)果婚禮上申鱼,老公的妹妹穿的比我還像新娘愤诱。我一直安慰自己,他們只是感情好捐友,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,785評(píng)論 6 392
  • 文/花漫 我一把揭開白布淫半。 她就那樣靜靜地躺著,像睡著了一般匣砖。 火紅的嫁衣襯著肌膚如雪昏滴。 梳的紋絲不亂的頭發(fā)上对人,一...
    開封第一講書人閱讀 51,624評(píng)論 1 305
  • 那天,我揣著相機(jī)與錄音牺弄,去河邊找鬼姻几。 笑死,一個(gè)胖子當(dāng)著我的面吹牛势告,可吹牛的內(nèi)容都是我干的鲜棠。 我是一名探鬼主播培慌,決...
    沈念sama閱讀 40,358評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼吵护!你這毒婦竟也來了盒音?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,261評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤馅而,失蹤者是張志新(化名)和其女友劉穎祥诽,沒想到半個(gè)月后瓮恭,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,722評(píng)論 1 315
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡屯蹦,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,900評(píng)論 3 336
  • 正文 我和宋清朗相戀三年登澜,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了阔挠。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片脑蠕。...
    茶點(diǎn)故事閱讀 40,030評(píng)論 1 350
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖谴仙,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情揩局,我是刑警寧澤,帶...
    沈念sama閱讀 35,737評(píng)論 5 346
  • 正文 年R本政府宣布谐腰,位于F島的核電站,受9級(jí)特大地震影響十气,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜砸西,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,360評(píng)論 3 330
  • 文/蒙蒙 一芹枷、第九天 我趴在偏房一處隱蔽的房頂上張望衅疙。 院中可真熱鬧鸳慈,春花似錦、人聲如沸走芋。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,941評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽挖函。三九已至状植,卻和暖如春怨喘,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背哲思。 一陣腳步聲響...
    開封第一講書人閱讀 33,057評(píng)論 1 270
  • 我被黑心中介騙來泰國(guó)打工吩案, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人徘郭。 一個(gè)月前我還...
    沈念sama閱讀 48,237評(píng)論 3 371
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像胧后,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子壳快,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,976評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容

  • 1 寫這篇博客的初衷 首先一句話概括:我想把這幾個(gè)月做的事情記錄下來,并且希望盡量詳細(xì)瘤旨,希望讀者讀了這篇文章能夠知...
    格老子閱讀 2,654評(píng)論 1 56
  • 在App開發(fā)的初期竖伯,代碼量不大,業(yè)務(wù)量比較少七婴,一個(gè)App作為一個(gè)單獨(dú)的模塊進(jìn)行開發(fā),往往問題不大打厘。但隨著業(yè)務(wù)的增多...
    AC編程閱讀 4,975評(píng)論 3 30
  • 最近有筒子在后臺(tái)問酋長(zhǎng)關(guān)于證券方面的問題,所以今天酋長(zhǎng)就給大家來嘮一嘮證券從業(yè)資格考試這檔子事牲芋! 證券從業(yè)資格考試...
    備考部落閱讀 830評(píng)論 0 6
  • 今天進(jìn)行了第3次網(wǎng)絡(luò)課程捺球。總體上氮兵,劉老師這次課程講的內(nèi)容很細(xì)致,特別是咨詢開始之前幾分鐘的事情泣栈。在此,不想做太多的...
    山水屋閱讀 314評(píng)論 1 2
  • RSA支持加解密掺涛,也支持簽名/驗(yàn)簽。使用rsa如何簽名/驗(yàn)簽?zāi)兀?1.rsa 簽名 2.rsa 驗(yàn)簽 3.調(diào)用
    ksnowlv閱讀 1,889評(píng)論 2 0