組件化開(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ě)兩個(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)?
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 已上傳 需要源碼可以下載后查看