Android 開(kāi)發(fā)之組件化環(huán)境搭建

組件化開(kāi)發(fā) 是適應(yīng)團(tuán)隊(duì)開(kāi)發(fā)的一種模式?

如果你一個(gè)項(xiàng)目有三人以上聯(lián)合開(kāi)發(fā) 你就會(huì)發(fā)現(xiàn)開(kāi)發(fā)協(xié)作以及效率會(huì)大不如從前 代碼臃腫 各種調(diào)用 各種重復(fù) 都是有可能會(huì)發(fā)生的 甚至?xí)霈F(xiàn)今天寫(xiě)明天錯(cuò) 這時(shí)候單一的module 的開(kāi)發(fā)模式 明顯已經(jīng)不適合再繼續(xù)使用了 所以組件化 應(yīng)運(yùn)而生(當(dāng)然還有插件化 以后會(huì)開(kāi)篇插件化以及插件化相關(guān)的框架介紹 今天只談組件化 以及組件化和插件化的區(qū)別)

下面給他兩個(gè)示例圖 區(qū)別組件化 和 插件化


組件化圖例
插件化圖例

?例圖已經(jīng)很明顯了 兩者從原理上來(lái)說(shuō)是有著本質(zhì)區(qū)別的 但最終目的都是為了提高開(kāi)發(fā)效率和團(tuán)隊(duì)協(xié)作能力

下面開(kāi)始環(huán)境搭建 本文以as 為例

新建一個(gè)項(xiàng)目 KidsDemo?

新建一個(gè)module library libmodel 放公共方法 或者 資源?

新建一個(gè)phone module businessmodel 功能模塊

案例使用了中間件路由 Arouter 具體使用我就不說(shuō)了 本文略長(zhǎng) 關(guān)于第三方 我會(huì)提供相關(guān)聯(lián)系?

阿里巴巴中間件?點(diǎn)擊了解Arouter路由

我的項(xiàng)目架構(gòu)?


項(xiàng)目架構(gòu)

我們只寫(xiě)兩個(gè)module 的 交互 和 通信 即 app 和 businessmodel 之間進(jìn)行

首先對(duì)preject 進(jìn)行配置?

打開(kāi)project 的 build.gradle 文件?

添加中間件


apply plugin: ‘com.alibaba.arouter’ dependencies {?

….?

classpath “com.alibaba:arouter-register:1.0.0”?

// NOTE: Do not place your application dependencies here; they belong?

// in the individual module build.gradle files?

}


提取遠(yuǎn)程依賴(lài) 設(shè)置開(kāi)關(guān) 在project 的 gradle.properties 中添加?

isDebug = true;// false debug 模式 true 發(fā)布模式 ;false 開(kāi)發(fā)模式不存在依賴(lài)關(guān)系


提取sdk管理供各model 調(diào)用 統(tǒng)一設(shè)置sdk版本

ext{?

android_compileSdkVersion = 25?

android_buildToolsVersion = ‘25.0.3’?

android_minSdkVersion = 16?

android_targetSdkVersion = 25?

app_versionCode = 1;?

app_versionName = “1.0”;

lib_fastjson = 'com.alibaba:fastjson:1.2.32'

lib_gson = 'com.google.code.gson:gson:2.6.1'

lib_xutils = 'org.xutils:xutils:3.5.0'

lib_router = 'com.alibaba:arouter-api:1.3.0'

lib_routercom = 'com.alibaba:arouter-compiler:1.1.4'

}


接著配置 libmodel 的 build.gradle 文件

compileSdkVersion rootProject.android_compileSdkVersion?

buildToolsVersion rootProject.android_buildToolsVersion

defaultConfig {

? ? minSdkVersion rootProject.android_minSdkVersion

? ? targetSdkVersion rootProject.android_targetSdkVersion

? ? versionCode rootProject.app_versionCode

? ? versionName rootProject.app_versionName

? ? testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"

}

compile lib_gson?

compile lib_xutils?

這里配置了sdk 的一些屬性 和 gson xutils 等工具

配置 app 的 build.gradle 文件


compileSdkVersion rootProject.android_compileSdkVersion?

buildToolsVersion rootProject.android_buildToolsVersion?

defaultConfig {?

applicationId “com.example.mysmall.kidsdemo”?

minSdkVersion rootProject.android_minSdkVersion?

targetSdkVersion rootProject.android_targetSdkVersion?

versionCode rootProject.app_versionCode?

versionName rootProject.app_versionName?

javaCompileOptions {?

annotationProcessorOptions {?

arguments = [ moduleName : project.getName() ]?

}?

}?

testInstrumentationRunner “android.support.test.runner.AndroidJUnitRunner”?

}?

buildTypes {?

release {?

minifyEnabled false?

proguardFiles getDefaultProguardFile(‘proguard-android.txt’), ‘proguard-rules.pro’?

}?

}?

resourcePrefix “app_” // 區(qū)別資源文件命名 防止重名問(wèn)題

compile lib_router?

annotationProcessor lib_routercom?

testCompile ‘junit:junit:4.12’?

compile project(‘:businessmodel’)?

compile project(‘:libmodel’)

添加中間件 以及 添加 libmodel businessmodel 依賴(lài)

配置 businessmodel 的 build.gradle 文件?

if (isDebug.toBoolean()) {

applyplugin:'com.android.library'

}else {

applyplugin:'com.android.application'

}

android {?

compileSdkVersion rootProject.android_compileSdkVersion?

buildToolsVersion rootProject.android_buildToolsVersion

defaultConfig {

? ? minSdkVersion rootProject.android_minSdkVersion

? ? targetSdkVersion rootProject.android_targetSdkVersion

? ? versionCode rootProject.app_versionCode

? ? versionName rootProject.app_versionName

? ? javaCompileOptions {

? ? ? ? annotationProcessorOptions {

? ? ? ? ? ? arguments = [ moduleName : project.getName() ]

? ? ? ? }

? ? }

? ? testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"

}

buildTypes {

? ? release {

? ? ? ? minifyEnabled false

? ? ? ? proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'

? ? }

}

resourcePrefix "business_" // 同上 區(qū)別命名

}

compile lib_router?

annotationProcessor lib_routercom?

compile project(‘:libmodel’)?

添加中間件 和 libmodel 依賴(lài)

然后我們要配置清單文件 manifast.xml?

main/ 包下創(chuàng)建 debug/包 然后復(fù)制你的manifast.xml 到 debug 下 修改 application 和 mainactivity 的屬性即可

然后在android 閉包下配置?

sourceSets {

main {

if (isDebug.toBoolean()) {

manifest.srcFile'src/main/debug/AndroidManifest.xml'

? ? ? ? }else {

manifest.srcFile'src/main/AndroidManifest.xml'

? ? ? ? }

}

}

好了 這樣就可以了 分別提供在library 和 application 情況下對(duì)manifast的訪(fǎng)問(wèn)


到這里基本配置 已經(jīng)完成了?

解釋一下 幾個(gè)點(diǎn)

第一 app 和 businessmodel 僅僅只配置了?

compile lib_router?

annotationProcessor lib_routercom // 阿里巴巴的中間件?

compile project(‘:libmodel’) // 共有基礎(chǔ)包?

這里并沒(méi)有配置 網(wǎng)絡(luò)請(qǐng)求 和 解析 工具 是因?yàn)槲以趌ibmodel 中已經(jīng)配置 app 和 buisnessmodel 中配置了 libmodel 直接調(diào)用即可 初始化 和 相關(guān)封裝 工作 都在 libmodel 中 并提供接口 共app 和 buisinessmodel 調(diào)用

第二 businessmodel 的相關(guān)配置?

if (isDebug.toBoolean()) {

applyplugin:'com.android.library'

}else {

applyplugin:'com.android.application'

}

不知道大家注意沒(méi)有 在project 的 gradle.properties 文件下 的 我給了一個(gè)屬性 isDebug = true;// false debug 模式 true 發(fā)布模式 這是個(gè)開(kāi)關(guān) 為了加載不同的busnessmodel 類(lèi)型 當(dāng)為true 是 businessmodel 是個(gè)library module 反之 是app module

當(dāng)然 還有的人將manifastxml 文件進(jìn)行了配置 配置了兩個(gè) 這個(gè)也是可以的 而我這里沒(méi)有配置 是因?yàn)槲乙恢笔钱?dāng)作module 開(kāi)發(fā)的 這種方式的配置方式是 在businessmodel 的main包下 創(chuàng)建一個(gè)debug包 將mainfastxml 文件復(fù)制一下 paste到 debug 包下 并去掉MainActivity的相關(guān)屬性即可

我們開(kāi)始編寫(xiě)libmodle 看一下 這個(gè)包的架構(gòu)?


libmodel結(jié)構(gòu)

base 基礎(chǔ)包 存儲(chǔ)baseactivity application 和 activity管理者?

router 路由包 管理路由 初始化 和 uri 地址管理?

utils 工具包 一些sp工具 gson 解析工具等



首先看一下 base 包?

AppContext 是上下問(wèn)管理類(lèi) 獲取application 的 上下文對(duì)象 具體代碼就不寫(xiě)了 稍后我會(huì)push 到 github 上?

AppManager app的堆棧管理 所有的activity?

BaseActivity activity 的父類(lèi) 和 activity 生命周期管理?

BaseChildApplication 各個(gè)modile 的application 的 父類(lèi) 管理同意初始化 以及內(nèi)存管理?

ApplicationAsLibrary 內(nèi)存管理的抽象方法

router 包下 ConstantRouterUri 所有的uri 的 常量類(lèi)?

utils 這個(gè)包就不說(shuō)了 無(wú)關(guān)緊要 只是展示作用而已?

稍后會(huì)有代碼上傳 如有需要 自己去pull 就i好了

現(xiàn)在我們開(kāi)始編碼 我想要app 和 businessmodule 進(jìn)行互相跳轉(zhuǎn) 互相傳值并展示?

app module 下只有兩個(gè)類(lèi) 一個(gè)是mainactivity 一個(gè)是appApplication

/**

* 作者: Nade_S on 2018/6/21.

*/public classMyAppextendsApplication{? ??

@Override? ??

public void onCreate() {

? ? ? ? super.onCreate();

? ? ? ? ARouter.openLog();? ? // 打印日志? ? ? ??

ARouter.openDebug();? // 開(kāi)啟調(diào)試模式(如果在InstantRun模式下運(yùn)行,必須開(kāi)啟調(diào)試模式!線(xiàn)上版本需要關(guān)閉,否則有安全風(fēng)險(xiǎn))? ? ? ?

?ARouter.init( this ); // 盡可能早违寞,推薦在Application中初始化? ? }

}


App的MainActivity

//@Route(path = "/app/activity/main")

@Route(path = ConstantRouterUri.AppMainUri)

public class MainActivityextends AppCompatActivity {

@Override

? ? protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

? ? ? ? setContentView(R.layout.activity_main);

? ? ? ? findViewById(R.id.app_jump_bt).setOnClickListener(new View.OnClickListener() {

@Override

? ? ? ? ? ? public void onClick(View v) {

ARouter.getInstance().build("/business/activity/main").withInt("age",33).withString("name","c羅").navigation();

? ? ? ? ? ? }

});

? ? ? ? int age = getIntent().getIntExtra("age",0);

? ? ? ? String name = getIntent().getStringExtra("name");

? ? ? ? Toast.makeText(this, "appMain---"+name+age, Toast.LENGTH_SHORT).show();

? ? }

}


為了直觀顯示 我把MainActivity 直接寫(xiě)在了這里

@Route(path = ConstantRouterUri.AppMainUri) 這樣也是可以的

我現(xiàn)在要做的操作的是 點(diǎn)擊跳轉(zhuǎn)到 businessmodel 下 MainActivity 頁(yè)面 并傳值過(guò)去

現(xiàn)在開(kāi)始編寫(xiě) businessmodel包下的MainActivity

//@Route(path = "/business/activity/main")

@Route(path = ConstantRouterUri.BusinessMainUri)

public class MainActivity extends AppCompatActivity {

? ? @Override

? ? protected void onCreate(Bundle savedInstanceState) {

? ? ? ? super.onCreate(savedInstanceState);

? ? ? ? setContentView(R.layout.b_activity_main);

? ? ? ? findViewById(R.id.business_jump_bt).setOnClickListener(new View.OnClickListener() {

? ? ? ? ? ? @Override

? ? ? ? ? ? public void onClick(View v) {

? ? ? ? ? ? ? ? ARouter.getInstance().build("/app/activity/main").withInt("age",34).withString("name","梅西").navigation();

? ? ? ? ? ? }

? ? ? ? });

? ? ? ? int age = getIntent().getIntExtra("age",0);

? ? ? ? String name = getIntent().getStringExtra("name");

? ? ? ? Toast.makeText(this, "businessMain---"+name+age, Toast.LENGTH_SHORT).show();

? ? }

}


business取值并展示 點(diǎn)擊返回到app包下的并傳值

效果如下:展示App/MainActivity 與 Business/MainActivty 相互傳值并顯示?


效果展示

當(dāng)然這是發(fā)布版 如果是開(kāi)發(fā)階段 直接在project的 build.gradle 設(shè)置開(kāi)關(guān)debug--ture/false即可

好了 本文結(jié)束 如有疑問(wèn) 留言或私信 demo 已上傳 需要源碼可以下載后查看

點(diǎn)擊下載demo

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末继蜡,一起剝皮案震驚了整個(gè)濱河市赚楚,隨后出現(xiàn)的幾起案子菱蔬,更是在濱河造成了極大的恐慌圆兵,老刑警劉巖太闺,帶你破解...
    沈念sama閱讀 206,723評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件糯景,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡省骂,警方通過(guò)查閱死者的電腦和手機(jī)蟀淮,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,485評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門(mén),熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)钞澳,“玉大人怠惶,你說(shuō)我怎么就攤上這事≡冢” “怎么了策治?”我有些...
    開(kāi)封第一講書(shū)人閱讀 152,998評(píng)論 0 344
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)逃延。 經(jīng)常有香客問(wèn)我览妖,道長(zhǎng),這世上最難降的妖魔是什么揽祥? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 55,323評(píng)論 1 279
  • 正文 為了忘掉前任讽膏,我火速辦了婚禮,結(jié)果婚禮上拄丰,老公的妹妹穿的比我還像新娘府树。我一直安慰自己,他們只是感情好料按,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,355評(píng)論 5 374
  • 文/花漫 我一把揭開(kāi)白布奄侠。 她就那樣靜靜地躺著,像睡著了一般载矿。 火紅的嫁衣襯著肌膚如雪垄潮。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 49,079評(píng)論 1 285
  • 那天,我揣著相機(jī)與錄音弯洗,去河邊找鬼旅急。 笑死,一個(gè)胖子當(dāng)著我的面吹牛牡整,可吹牛的內(nèi)容都是我干的藐吮。 我是一名探鬼主播,決...
    沈念sama閱讀 38,389評(píng)論 3 400
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼逃贝,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼谣辞!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起沐扳,我...
    開(kāi)封第一講書(shū)人閱讀 37,019評(píng)論 0 259
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤泥从,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后迫皱,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體歉闰,經(jīng)...
    沈念sama閱讀 43,519評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,971評(píng)論 2 325
  • 正文 我和宋清朗相戀三年卓起,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了和敬。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,100評(píng)論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡戏阅,死狀恐怖昼弟,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情奕筐,我是刑警寧澤舱痘,帶...
    沈念sama閱讀 33,738評(píng)論 4 324
  • 正文 年R本政府宣布,位于F島的核電站离赫,受9級(jí)特大地震影響芭逝,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜渊胸,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,293評(píng)論 3 307
  • 文/蒙蒙 一旬盯、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧翎猛,春花似錦胖翰、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,289評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至疫稿,卻和暖如春培他,著一層夾襖步出監(jiān)牢的瞬間鹃两,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 31,517評(píng)論 1 262
  • 我被黑心中介騙來(lái)泰國(guó)打工靶壮, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留怔毛,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 45,547評(píng)論 2 354
  • 正文 我出身青樓腾降,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親碎绎。 傳聞我的和親對(duì)象是個(gè)殘疾皇子螃壤,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,834評(píng)論 2 345

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