ModuleCommunication 旨在解决模块间的通信需求,可以让模块间的代码在依旧存在于其自己的模块的前提下,实现能够互相访问而不需要下沉到公共模块。以此来解决公共模块因为各个模块下沉代码而导致的不断膨胀的问题
每个模块使用此库生成属于自己模块的跳转 Activity 的帮助类,也是可以做到市面上那些 router 的功能,框架代码极少,风险可控!(不过仅限您一个小项目可以这么做,如果没有插件化完全够用)
功能示意图
我们常见的模块化架构模型基本上就是这样的,本库在不影响任何结构的情况下即可做到通信
如下图所示,把所有 module 需要共享的代码全部暴露到 communication
模块下,然后想要使用共享代码的 module 使用 compileOnly 方式引入 communication
模块就可以了
💡compileOnly 方式导入 在打包时,整个 module 都不会打进安装包,可以说是起一个桥梁作用。
通信 module
可以配置多个点此查看
特色功能
1、支持模块间共享 Java 或 Kotlin 代码
2、支持模块间共享 res 文件夹下的资源
3、支持模块间共享 assets 资源
使用步骤
在开始之前可以给项目一个Star吗?非常感谢,你的支持是我唯一的动力。欢迎Star和Issues!
一、引入插件
1、在 项目根目录 的 build.gradle
里依赖插件
buildscript {
dependencies {
//必须项 👇
classpath 'io.github.FlyJingFish.ModuleCommunication:module-communication-plugin:1.0.7'
}
}
2、在 项目根目录 的 build.gradle
里依赖插件
plugins {
//必须项 👇下边版本号根据你项目的 Kotlin 版本决定👇
id 'com.google.devtools.ksp' version '1.8.10-1.0.9' apply false
}
二、新增负责通信的 module
-
1、例如新建一个名为
communication
的module(下文将以communication
为例介绍) -
2、在
communication
的build.gradle
添加
//必须项 👇
plugins {
...
id 'communication.module'
}
- 3、在项目根目录的
gradle.properties
新增如下配置
CommunicationModuleName = communication
三、开始使用
1⃣️ 共享 Kotlin 或 Java 代码
以下面代码结构为例介绍下
下边的暴露代码在本项目的 lib-user
模块中
- 1、在需要暴露代码的模块
lib-user
的build.gradle
添加
//必须项 👇
plugins {
...
id 'communication.export'
}
- 2、在需要暴露给其他module使用的逻辑代码接口上使用
@ExposeInterface
@ExposeInterface
interface UserHelper {
fun getUser():User
}
- 3、把
@ExposeInterface
注解的接口类涉及的数据类上使用@ExposeBean
@ExposeBean
data class User (val id:String)
- 4、在
@ExposeInterface
注解的接口类的实现类上使用@ImplementClass(UserHelper::class)
,实现类必须只有一个
@ImplementClass(UserHelper::class)
class UserHelperImpl :UserHelper {
override fun getUser():User {
Log.e("UserHelperImpl","getUser")
return User("1111")
}
}
- 5、调用 gradle 命令,生成共享代码
communication -> generateCommunication
调用这个命令,将会生成共享代码。不调用直接运行代码可能会报错,一般报错最多次数为项目的 module 个数,即可生成完所有共享代码,如下图示
暴露的代码出现在了 communication
模块下
- 6、在需要使用
lib-login
模块 上引入通信模块communication
a、lib-login
引入通信模块
compileOnly(project(":communication"))
注意引入方式必须是 compileOnly ,否则会导致打包失败。并且在哪个 module 中使用就在哪引入
b、如果 lib-login
也已经引入过 communication.export
插件,就无需配置这一步(不报错找不到类就无需引入)
dependencies {
//必须项 👇(可以直接放在公共 module)
implementation 'io.github.FlyJingFish.ModuleCommunication:module-communication-annotation:1.0.7'
}
- 7、在
lib-login
模块使用lib-user
暴露出来的的代码
class LoginActivity: AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
//getSingleInstance 是获取单例 getNewInstance 是获取新的对象
val userHelper = ImplementClassUtils.getSingleInstance<UserHelper>(UserHelper::class)
val user = userHelper.getUser()
Log.e("user",""+user)
}
}
2⃣️ 共享 res 或 assets 文件夹下的资源
以下面代码结构为例介绍下
- 1、
lib-login
需要暴露 res 或 assets 代码,可在build.gradle
设置如下代码:
communicationConfig{
exposeResIds.addAll(arrayOf(
"R.drawable.login_logo",
"R.string.login_text",
"R.array.weekname",
"R.style.LoginAppTheme",
"R.color.color_theme",
"R.color.color_white_both"
))
//直接可以输入 assets 下的文件夹或者文件路径即可
exposeAssets.addAll(arrayOf(
"matching",
"swipe_like"
))
}
直接调用下边命令即可
共享之后在使用共享资源之前需要把下边这项设置关掉
根目录下的 gradle.properties
的 android.nonTransitiveRClass
设置为 false
(否则 R 文件的包名只能用通信module的,打包后会出现异常)
- 2、在
lib-user
中使用资源即可
class UserActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_user)
findViewById<ImageView>(R.id.iv_image).setImageResource(R.drawable.login_logo)
val text = R.string.login_text
val theme = R.style.LoginAppTheme
}
}
四、番外(非必须项)
- 1、如果你想定义更多的通信模块,而不是使用同一个,可以在使用
'communication.export'
module 加入以下配置项
plugins {
id("communication.export")
}
communicationConfig{
exportModuleName = "communication2"
}
这样共享代码会转移到 communication2
这个 module 中
- 2、调用以下命令可一键暴露所有代码
混淆规则
下边是涉及到本库的一些必须混淆规则
# ModuleCommunication必备混淆规则 -----start-----
-keepnames @com.flyjingfish.module_communication_annotation.ExposeInterface class * {*;}
-keepnames class * implements com.flyjingfish.module_communication_annotation.BindClass
-keep class * implements com.flyjingfish.module_communication_annotation.BindClass{
public <init>();
}
# ModuleCommunication必备混淆规则 -----end-----
常见问题
1、删除某一个类或资源后,通信 module 中依然存在删除的代码
- 这种情况下建议直接 clean 项目,再次重新调用 generateCommunication 命令。