模块化构建项目
项目展示:
这里分成了5个模块和一个base模块
模块构成展示:
在建立新的module后看看settings.gradle(即图中标的1)中有没有引入你新建的module,一般会自动引入的,如果没有,可能IDE犯病了,自己手动引一下
Arouter配置
ARouter里面的最新版本:
一般只会使用到前面两个
module中的设置
在每个子module和BaseModule中的gradle中设置以下内容
在每个子module和BaseModule:
android {}中的defaultConfig {}里添加
javaCompileOptions {
annotationProcessorOptions {
arguments = [moduleName: project.getName()]
}
}
子module:
在dependencies {}中添加
annotationProcessor 'com.alibaba:arouter-compiler:1.1.4'
BaseModule:
在dependencies {}中添加
api 'com.alibaba:arouter-api:1.3.1'
App中的设置
设置Application初始化ARouter
public class MyApplication extends Application {
@Override
public void onCreate() {
super.onCreate();
initRouter(this);
}
public static void initRouter(Application application) {
if (BuildConfig.DEBUG) {
ARouter.openLog(); // 打印日志
ARouter.openDebug(); // 开启调试模式(如果在InstantRun模式下运行,必须开启调试模式!线上版本需要关闭,否则有安全风险)
}
ARouter.init(application);
}
}
别忘了在AndroidManifest.xml中引入MyApplication
ARouter的页面跳转
ARouter官网上介绍:
ARouter.getInstance().build("/test/activity").navigation();
@Route(path = "/test/activity")
public class YourActivity extend Activity {
...
}
在我自己的项目里,我在BaseModule中封装了一个RouteUtils,里面内容如下:
public class RouteUtils {
public static final String Home_Fragment_Main = "/home/main";
public static final String Hospital_Fragment_Main = "/hospital/main";
public static final String Hot_Fragment_Main = "/hot/main";
public static final String Report_Fragment_Main = "/report/main";
public static final String Mine_Fragment_Main = "/mine/main";
public static Fragment getHomeFragment() {
Fragment fragment = (Fragment) ARouter.getInstance().build(Home_Fragment_Main).navigation();
return fragment;
}
public static Fragment getHospitalFragment() {
Fragment fragment = (Fragment) ARouter.getInstance().build(Hospital_Fragment_Main).navigation();
return fragment;
}
public static Fragment getHotFragment() {
Fragment fragment = (Fragment) ARouter.getInstance().build(Hot_Fragment_Main).navigation();
return fragment;
}
public static Fragment getReportFragment() {
Fragment fragment = (Fragment) ARouter.getInstance().build(Report_Fragment_Main).navigation();
return fragment;
}
public static Fragment getMineFragment() {
Fragment fragment = (Fragment) ARouter.getInstance().build(Mine_Fragment_Main).navigation();
return fragment;
}
}
在对应的module内,所需要跳转的页面设置如下:
@Route(path = RouteUtils.Home_Fragment_Main)
public class HomeFragment extends BaseFragment {}
最后在App中的build.gradle中添加你需要引入的module,类似于下面的内容:
implementation project(':baselibrary')
implementation project(':module_home')
implementation project(':module_hospital')
implementation project(':module_hot')
implementation project(':module_report')
if (isShowModule.toBoolean()) {
implementation project(':module_mine')
}
isShowModule.toBoolean()是什么鬼,别急,待会再告诉你
到此ARouter的配置就完成了
gradle配置
由于使用了模块化,建立了多个模块,因此修改版本号、修改引入的第三方库就变得麻烦,稍有不慎,忘记改了哪个,项目也许就会报错,这个时候使用强大的gradle管理各个module就显得尤为重要
添加扩展块
首先在总工程下的新建一个common.gradle文件,里面加入一个扩展块,内容如下:
ext {
android = [
compileSdkVersion: 27,
minSdkVersion : 19,
targetSdkVersion : 27,
versionCode : 1,
versionName : "1.0"
]
dependencies = [
"appcompat-v7" : 'com.android.support:appcompat-v7:27.1.1',
//最新版
"constraint-layout" : 'com.android.support.constraint:constraint-layout:1.0.2',
"fastjson" : 'com.alibaba:fastjson:1.1.68.android',
"pickerview" : 'com.contrarywind:Android-PickerView:4.1.4',
"multidex" : 'com.android.support:multidex:1.0.1',
"recyclerview" : 'com.android.support:recyclerview-v7:27+',
"SmartRefreshLayout" : 'com.scwang.smartrefresh:SmartRefreshLayout:1.0.5.1',
//没有使用特殊Header,可以不加这行
"SmartRefreshHeader" : 'com.scwang.smartrefresh:SmartRefreshHeader:1.0.5.1',
//BaseRecyclerViewAdapterHelper
"BaseRecyclerViewAdapterHelper": 'com.github.CymChad:BaseRecyclerViewAdapterHelper:2.9.30',
"design" : 'com.android.support:design:27+',
"cardview" : 'com.android.support:cardview-v7:27+',
"glide" : 'com.github.bumptech.glide:glide:4.7.1',
"glide_compiler" : 'com.github.bumptech.glide:compiler:4.7.1',
//arouter路由
"arouter-api" : 'com.alibaba:arouter-api:1.3.1',
"arouter-compiler" : 'com.alibaba:arouter-compiler:1.1.4'
]
}
然后在总工程下的build.gradle中引入common文件
//引入common文件
apply from: this.file('common.gradle')
当然也可以不建common文件,直接将整个扩展块加入到总工程下的build.gradle文件(即开头第二张图中标的2)的最后面,但我个人感觉建一个common文件比较好便于管理
在各个module中使用以下方式引入
api rootProject.ext.dependencies.glide
这里是使用api还是implementation 根据自己的实际情况来定
可以参考我git上上传的项目
api和implementation区别
他们的区别:implementation就只有本module能访问到,api是依赖于此module的module也能访问到,但是api编译效率低,implementation有点像沙箱只处理自己的
将module作为单独的App运行
模块化的好处就是可以把不同模块分离开来,分别编译运行,不仅分工更加明确,耦合性降低,同时降低了编译时间,提高了开发效率,所以必然是可以将其中一个module作为一个App使用的,那要怎么做呢,往下看
你需要先设置一个总变量
在总工程下的gradle.properties (即开头第二张图中标的3)里面添加一个变量,后面需要用这个变量判断是否当做一个module显示
#是否当做Module显示,false就是不当做module显示,true就是当做module,更改值就可以看到神奇的效果
#isShowModule=false
isShowModule=true
还记得前面那个isShowModule.toBoolean()么,现在就来告诉你这是什么
由于你在gradle.properties 里设置了一个全局变量,所以在总工程下的任何一个子项目都可以使用这个变量,
isShowModule.toBoolean()的意思就是获取到isShowModule的值
if (isShowModule.toBoolean()) {
implementation project(':module_mine')
}
这段代码的意思就是如果isShowModule的值为true才引入module否则不引入该module
这样就可以了么?当然不是,还有两个地方需要设置
在这个项目中我是拿 module_mine 这个module来判断的,所以需要在module_mine中的build.gradle做以下设置:
//hasProperty(isShowApp)判断是否有isShowApp变量 为true就以单独的module形式出现,为false就以App形式出现
if (hasProperty('isShowModule') ? isShowModule.toBoolean() : false) {
apply plugin: 'com.android.library'
} else {
apply plugin: 'com.android.application'
}
另一个需要做修改的地方,同样是在module_mine中的build.gradle中,在android{}中:
sourceSets {
main {
if (isShowModule.toBoolean()) {
manifest.srcFile 'src/main/AndroidManifest.xml'
} else {
manifest.srcFile 'src/main/app/AndroidManifest.xml'
}
}
}
App文件夹下的AndroidManifest.xml:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.test.module_mine">
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity android:name=".LoginActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
main文件夹下的AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.test.module_mine">
<application>
<activity android:name=".LoginActivity"></activity>
</application>
</manifest>
到此整个框架就完成了