Android組件化開發(fā)實(shí)踐

更新:Android組件化之通信(多模塊,多進(jìn)程)

Android項(xiàng)目中代碼量達(dá)到一定程度,編譯將是一件非常痛苦的事情,短則一兩分鐘,長則達(dá)到五六分鐘。Android studio推出instant run由于各種缺陷一般情況下是被關(guān)閉的……
組件化開發(fā)可以有效降低代碼模塊的耦合度,使代碼架構(gòu)更加清晰,同時(shí)模塊化的編譯可以有效減少編譯時(shí)間,當(dāng)然總的編譯時(shí)間是不會減少的,只是App模塊化之后開發(fā)某個(gè)模塊時(shí),只需要編譯特定模塊,可以快速編譯調(diào)試。

原理

組件化和插件化有些同學(xué)有些迷惑,簡單來說組件化是在編譯期分模塊,插件化是在運(yùn)行期。一般插件化用于動態(tài)修復(fù)bug或者動態(tài)更新模塊,相對來說黑科技更多一些。

正常一個(gè)App中可以有多個(gè)module,但是一般只會有一個(gè)module是設(shè)置為application的,其他均設(shè)置為library,組件化開發(fā)就是要每個(gè)module都可以運(yùn)行起來,因此在開發(fā)期間每個(gè)module均設(shè)置為application,發(fā)布時(shí)再進(jìn)行合并。

實(shí)踐

本文主要介紹一下項(xiàng)目組件化開發(fā)過程碰到的問題和解決辦法,這里以
ModularizationApp項(xiàng)目為例。ModularizationApp是一個(gè)組件化的app:

Paste_Image.png
Paste_Image.png
Paste_Image.png
Paste_Image.png
Paste_Image.png
  • 架構(gòu)

Paste_Image.png

其中App是主application,ModuleA和ModuleB是兩個(gè)業(yè)務(wù)模塊,Library是基礎(chǔ)模塊,包含所有模塊需要的依賴庫,以及一些工具類:如網(wǎng)絡(luò)訪問、時(shí)間工具等。代碼結(jié)構(gòu)如圖:

Paste_Image.png
  • Module作為application開發(fā)

ModuleA和ModuleB是相對獨(dú)立的業(yè)務(wù)模塊,可以分別進(jìn)行開發(fā),編譯時(shí)只編譯自身,具體實(shí)現(xiàn)時(shí)在gradle.properties中設(shè)置變量,如:IsBuildMudle=false
在模塊的的build.gradle中:

if (IsBuildMudle.toBoolean()) {
    apply plugin: 'com.android.application'
} else {
    apply plugin: 'com.android.library'
}

在主模塊的build.gradle中設(shè)置:

    if (!IsBuildMudle.toBoolean()) {
        compile project(':ModuleA')
        compile project(':ModuleB')
    } else {
        compile project(':Library')
    }

這樣每個(gè)module就可以獨(dú)立安裝使用了,注意在修改IsBuildMudle的值時(shí),一定要sync gradle
當(dāng)module單獨(dú)運(yùn)行和作為module運(yùn)行時(shí),其activity在manifest中設(shè)置也會不同,這里可以根據(jù)IsBuildMudle設(shè)置不同的manifest:

    sourceSets {
        main {
            if (IsBuildMudle.toBoolean()) {
                manifest.srcFile 'src/main/debug/AndroidManifest.xml'
            } else {
                manifest.srcFile 'src/main/release/AndroidManifest.xml'
            }
        }
    }

分別在不同的目錄下創(chuàng)建manifest文件。一定要注意兩個(gè)manifest的同步問題,否則出現(xiàn)了莫名其名的bug,還找不到原因……

  • 資源沖突問題

當(dāng)分別開發(fā)模塊時(shí),容易出資源重復(fù)命名的問題,可以在build.gradle中設(shè)置

resourcePrefix "module1_"

通過給模塊設(shè)置不同的資源前綴,可以避免重復(fù)命名。

  • Activity跳轉(zhuǎn)問題

拆分業(yè)務(wù)代碼時(shí),自然會涉及到跨module的Activity跳轉(zhuǎn),當(dāng)單獨(dú)編譯時(shí),自然是不能獲取到其他模塊的引用的。有幾種方式可以實(shí)現(xiàn)跨模塊的喚起Activity:

隱式啟動
通過設(shè)置intent-filter實(shí)現(xiàn),這需要在manifest中插入大量代碼,同時(shí)也降低了安全性(其他app就可以通過這種方式隨意啟動)。
通過類名跳轉(zhuǎn)
Android業(yè)務(wù)組件化開發(fā)實(shí)踐提出了一種通過類名跳轉(zhuǎn)的方式,使用腳本生成Rlist類,比較方便快捷,但感覺不方便activity間傳遞數(shù)據(jù)。
Scheme跳轉(zhuǎn)
Scheme的方式是建立映射表,集中處理Activity,這種方式可以傳遞一定的數(shù)據(jù)。Activity傳遞大量數(shù)據(jù)時(shí)可以通過EventBus來進(jìn)行傳遞(其實(shí)即使通過intent顯示啟動,也不要把大量數(shù)據(jù)放置在intent中,intent對數(shù)據(jù)大小有限制)。
在進(jìn)行本次實(shí)踐時(shí)找到github上的一個(gè)url Router,同時(shí)支持http和程序內(nèi)Activity跳轉(zhuǎn),而且通過注解的方式進(jìn)行,使用非常方便,于是引入到了項(xiàng)目中。項(xiàng)目地址ActivityRouter。ActivityRouter的readme中已經(jīng)有比較詳細(xì)的wiki,但是還有一些需要注意的:

依賴問題:

ActivityRouter使用了apt方式,因此每個(gè)使用的module中均需要設(shè)置

apt 'com.github.mzule.activityrouter:compiler:1.1.5'

注意是每個(gè)module,在Library module中設(shè)置

classpath 'com.neenbedankt.gradle.plugins:android-apt:1.8'

即可。

多module問題

ActivityRouter通過注解在編譯時(shí)生成mapping,如果多個(gè)module設(shè)置依賴,就會生成多個(gè)java文件,導(dǎo)致源文件重復(fù),編譯出錯,ActivityRouter目前提供了解決方法,但是還沒有正式發(fā)布版本,可以設(shè)置:

compile 'com.github.mzule.activityrouter:activityrouter:1.1.9' 
apt 'com.github.mzule.activityrouter:compiler:1.1.6'

使用。使用在application中注解:

@Modules({"app", "moduleA", "moduleB"})
public class ModularizationApplication extends Application {
}

每個(gè)module中創(chuàng)建空java類注解:

@Module("moduleA")
public class ModuleA {
}

具體可以clone ModularizationApp查看代碼。

編譯運(yùn)行

當(dāng)在gradle.properties中設(shè)置IsBuildMudle=true時(shí),可以獨(dú)立運(yùn)行每個(gè)module,獨(dú)立運(yùn)行調(diào)試,當(dāng)設(shè)置IsBuildMudle=false,可以編譯運(yùn)行整個(gè)project,注意IsBuildMudle變量設(shè)置改變時(shí),要對gradle進(jìn)行sync。

運(yùn)行過程中有什么問題可以評論或者在github中提issue。

參考:
http://kymjs.com/code/2016/10/18/01
https://github.com/mzule/ActivityRouter
https://github.com/liangzhitao/ComponentizationApp

Other

歡迎關(guān)注公眾號wutongke,每天推送移動開發(fā)前沿技術(shù)文章:

wutongke

推薦閱讀:

Android 組件化開發(fā)原理和配置

Android組件化開發(fā)實(shí)踐

Android組件化之通信(多模塊,多進(jìn)程)

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容