目录
模块化的开发流程
模块化的开发流程
- 首先 我们建立一个主App,主app用来控制触发进入各个模块的入口,只是一个外壳,所有的逻辑在各个模块组件内部开发,各个模块以及外壳的app通信是采用阿里的路由框架进行的,稍后我会搭建一个可以各个模块的配置,以及运行环境。大家直接实战进行吧,在网上搜索一堆的模块化开发博客,倒不如自己亲自实践一下,原理都是一样,实践出真知吧。
- 首先我的AS是3.6.1 版本的,我们搭建一个主工程,我这里暂且命名时StoreApp,然后再在这个主工程下面创建三个子module工程和一个lib工程,分别命名module工程为home,mine,store工程,lib工程名为baselib,而lib工程主要用来依赖各个工程所需要依赖的资源库 。创建好了这些以后,我们知道module工程是可以独立运行的。接下来,我们得配置module工程为lib库作为依赖了。
- 在主工程的 gradle.properties文件下配置值三个控制home,mine,store作为库工程还是独立调试的可运行的module工程。我是这样配置的三个参数的:
#控制子工程是以lib还是moudle的形式
isShowHome = true
isShowMine = true
isShowStore= true
- 三个module工程的gradle配置都是一样的配置,这里我以home为例。在gradle的顶部加一个if判断句:
if (!isShowHome.toBoolean()) {
apply plugin: 'com.android.application'
} else {
apply plugin: 'com.android.library'
} 这个是用来判断它为module还是lib库的
接下来在我们看到包名applicationId在其中也添加一个判断语句:
if (!isShowHome.toBoolean()) {
applicationId "com.android.xzl.home"
}
- 接下来我们配置一下清单文件的资源:
sourceSets {
main {
//控制两种模式下的资源和代码配置情况
if (!isShowHome.asBoolean()) {
manifest.srcFile 'src/main/module/AndroidManifest.xml'
} else {
manifest.srcFile 'src/main/AndroidManifest.xml'
//集成开发模式下排除debug文件夹中的所有Java文件
java {
exclude 'debug/**'
}
}
}
}
我们看到有个路径,我们没有建立这个时候,在main目录下建立一个module文件夹,但是然后将我们清单文件复制一份进去,但是要做一些修改。将application下的各种配置都删除掉,然后就留下一个theme属性就行了。我给大家先贴出一份我的module工程下的清单文件,然后是建立的module文件夹下的清单文件代码:
home的module工程下的清单文件:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.android.xzl.home">
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
而我们自己建立的文件夹的清单文件为:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.android.xzl.home">
<application
android:theme="@style/AppTheme">
<activity android:name=".MainActivity"/>
</application>
</manifest>
- 好了,其余的mine和store的module工程gradle配置是一样的,但是要对应我们的之前在gradle.properties的配置的三个布尔值,记得把把那个改一下。当然我们也可以用一个布尔值配置三个moudle工程开关,这个看个人的喜欢。
- 接下来,我们配置一下baselib的库,首先我们用的是阿里的路由框架用来各个模块的通信,传参。在gradle中依赖一下:
api 'com.alibaba:arouter-api:1.4.1'
annotationProcessor 'com.alibaba:arouter-compiler:1.2.1'
这里注意一下,我没有用implementation而是用了api,大家可以自行百度,看一下区别。接下来,我们在defaultConfig中还要加入:
javaCompileOptions {
annotationProcessorOptions {
arguments = [AROUTER_MODULE_NAME: project.getName()]
}
}
这下我们就配置好了路由框架了。这里有个注意点各个子工程要是用到路由框架都要再次在gradle中的依赖出加入:
annotationProcessor 'com.alibaba:arouter-compiler:1.2.1' 和
javaCompileOptions {
annotationProcessorOptions {
arguments = [AROUTER_MODULE_NAME: project.getName()]
}
}
这个依赖,不然编译的时候会报alibaba:arouter找不到的错误。
- 接下来,我们在baselib库下建立BaseApplication,
import com.alibaba.android.arouter.launcher.ARouter;
public class BaseApplication extends Application {
private static BaseApplication instance;
@Override
public void onCreate() {
super.onCreate();
instance=this;
initRouter();
}
public static BaseApplication getInstance(){
return instance;
}
private void initRouter(){
if (BuildConfig.DEBUG) {
//一定要在ARouter.init之前调用openDebug
ARouter.openDebug();
ARouter.openLog();
}
ARouter.init(this);
}
}
然后建立一个路劲类RouterPath:
/**
* create by libo
* create on 2018/12/25
* description 路径跳转配置类
*/
public class RouterPath {
public static final String ROUTER_HOME = "/home/activity";
public static final String ROUTER_MINE = "/mine/activity";
public static final String ROUTER_STORE = "/store/activity";
}
- 然后我们在主工程还有各个模块都依赖这个baselib
- 接下来我们在主工程的moudle下,
implementation project(path: ':baselib')
annotationProcessor 'com.alibaba:arouter-compiler:1.2.1'
implementation project(path: ':mine')
implementation project(path: ':home')
implementation project(path: ':store')
再次强调一下:使用路由框架还需要依赖:annotationProcessor 'com.alibaba:arouter-compiler:1.2.1'这个,还有加上
javaCompileOptions {
annotationProcessorOptions {
arguments = [AROUTER_MODULE_NAME: project.getName()]
}
}
- 然后我们在主工程建立MainApplication继承baselib库的BaseApplication,记住在清单文件中声明一下:代码:
/**
* author : wulei
* e-mail :
* time : 2020/04/04
* desc :
*/
public class MainApplication extends BaseApplication {
@Override
public void onCreate() {
super.onCreate();
}
}
- 如果你的jdk版本过低,在各个模块的gradle中加入:
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
- 然后你就可以写你的逻辑代码了我再我的主工程的MainActivity下的代码:
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
private Button mBtHome;
private Button mBtMine;
private Button mBtStore;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ARouter.getInstance().inject(this);
mBtHome = (Button) findViewById(R.id.bt_home);
mBtMine = (Button) findViewById(R.id.bt_mine);
mBtStore = (Button) findViewById(R.id.bt_store);
mBtHome.setOnClickListener(this);
mBtMine.setOnClickListener(this);
mBtStore.setOnClickListener(this);
}
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.bt_home:
ARouter.getInstance().build(RouterPath.ROUTER_HOME).
withString("home_msg", "我传递了home页面过去").navigation();
break;
case R.id.bt_mine:
ARouter.getInstance().build(RouterPath.ROUTER_MINE).
withString("mine_msg", "我是磊磊哥啊!!!!").navigation();
break;
case R.id.bt_store:
ARouter.getInstance().build(RouterPath.ROUTER_STORE).
withString("store_msg", "进入了商店,买个东西再走吧!!!").navigation();
break;
}
}
布局文件如下:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity"
android:orientation="vertical">
<Button
android:id="@+id/bt_home"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="跳转home界面"/>
<Button
android:id="@+id/bt_mine"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="跳转我的界面"/>
<Button
android:id="@+id/bt_store"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="跳转商店界面"/>
</LinearLayout>
14.我的home页面的代码如下:
@Route(path = RouterPath.ROUTER_HOME)
public class MainActivity extends AppCompatActivity {
@Autowired()
String home_msg;
private TextView mTvHome;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_home);
ARouter.getInstance().inject(this);
mTvHome = (TextView) findViewById(R.id.tv_home);
mTvHome.setText(home_msg+"");
}
}
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity"
android:gravity="center">
<TextView
android:id="@+id/tv_home"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
/>
</LinearLayout>
15.在mine的逻辑代码如下:
@Route(path = RouterPath.ROUTER_MINE)
public class MainActivity extends AppCompatActivity {
@Autowired
String mine_msg;
private TextView mTvMine;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
ARouter.getInstance().inject(this);
setContentView(R.layout.activity_mine);
mTvMine = (TextView) findViewById(R.id.tv_mine);
mTvMine.setText(mine_msg);
}
}
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<TextView
android:id="@+id/tv_mine"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="这是默认的我的界面!!!!"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
16:在store下的代码:
@Route(path= RouterPath.ROUTER_STORE)
public class MainActivity extends AppCompatActivity {
@Autowired
String store_msg;
private TextView mTvStore;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_store);
ARouter.getInstance().inject(this);
mTvStore = (TextView) findViewById(R.id.tv_store);
mTvStore.setText(store_msg);
}
}
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<TextView
android:id="@+id/tv_store"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="这是商店的默认界面!!!!!!"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
哈哈哈,最后警告一下,新建的module下的布局文件的名字不要全部一样的,到时候有冲突的额!!!接下来我们就可以试着运行项目了。