6模块Android项目跨模块主Activity跳转循环依赖问题求助
解决方案:跨模块Activity跳转的无循环依赖实现方案
核心思路
通过契约接口+全局导航器或统一隐式Intent规则两种方式,彻底打破模块间的依赖循环,实现无需直接依赖目标模块即可完成跳转。
方案一:基于契约接口的全局导航器
1. 创建公共基础模块(仅定义契约,无业务模块依赖)
该模块仅存放跳转相关的接口、常量,不引入任何业务模块依赖,从根源避免循环。
定义跳转契约接口
// 公共模块中 interface ModuleNavigator { fun navigateToModule(context: Context, moduleId: String) }
定义模块唯一标识常量
// 公共模块中 object ModuleConstants { const val MODULE_A = "module_a" const val MODULE_B = "module_b" const val MODULE_C = "module_c" const val MODULE_D = "module_d" const val MODULE_E = "module_e" const val MODULE_APP = "module_app" }
实现全局导航器管理类
// 公共模块中 object GlobalNavigator { private val navigatorMap = mutableMapOf<String, ModuleNavigator>() // 注册模块跳转逻辑 fun register(moduleId: String, navigator: ModuleNavigator) { navigatorMap[moduleId] = navigator } // 执行跳转 fun jumpToModule(context: Context, moduleId: String) { navigatorMap[moduleId]?.navigateToModule(context, moduleId) ?: throw IllegalArgumentException("未找到模块[$moduleId]的跳转逻辑") } }
2. 业务模块注册跳转逻辑
所有业务模块(含Application模块)仅依赖公共模块,在初始化阶段注册自身的跳转逻辑:
示例:Module A的注册代码
// Module A内部 class ModuleAInit { fun init() { GlobalNavigator.register(ModuleConstants.MODULE_A) { context, _ -> val intent = Intent(context, ModuleAMainActivity::class.java) context.startActivity(intent) } } }
Application模块统一初始化所有注册
// Application模块的Application类 class App : Application() { override fun onCreate() { super.onCreate() // 初始化所有模块的跳转注册 ModuleAInit().init() ModuleBInit().init() ModuleCInit().init() ModuleDInit().init() ModuleEInit().init() // 注册自身的跳转逻辑 GlobalNavigator.register(ModuleConstants.MODULE_APP) { context, _ -> val intent = Intent(context, AppMainActivity::class.java) context.startActivity(intent) } } }
3. 跨模块跳转调用
在任意模块中,直接通过公共模块的全局导航器完成跳转,无需依赖目标模块:
// 例如在Module B中跳转到Module A GlobalNavigator.jumpToModule(context, ModuleConstants.MODULE_A)
方案二:统一隐式Intent规则
1. 公共模块定义Intent常量
// 公共模块中 object IntentRules { const val APP_SCHEME = "myapp" const val ACTION_MODULE_A = "com.myapp.action.MODULE_A" const val ACTION_MODULE_B = "com.myapp.action.MODULE_B" const val ACTION_MODULE_C = "com.myapp.action.MODULE_C" const val ACTION_MODULE_D = "com.myapp.action.MODULE_D" const val ACTION_MODULE_E = "com.myapp.action.MODULE_E" const val ACTION_MODULE_APP = "com.myapp.action.MODULE_APP" }
2. 各模块Activity配置Intent Filter
在每个模块的主Activity的AndroidManifest.xml中配置唯一的Action和Scheme:
<activity android:name=".ModuleAMainActivity" android:exported="true"> <intent-filter> <action android:name="com.myapp.action.MODULE_A" /> <category android:name="android.intent.category.DEFAULT" /> <data android:scheme="myapp" /> </intent-filter> </activity>
3. 跨模块跳转调用
在任意模块中,通过隐式Intent完成跳转:
// 例如在Module C中跳转到Application模块 val intent = Intent(IntentRules.ACTION_MODULE_APP).apply { scheme = IntentRules.APP_SCHEME flags = Intent.FLAG_ACTIVITY_NEW_TASK } context.startActivity(intent)
关键注意事项
- 公共模块绝对不能依赖任何业务模块,只能被业务模块依赖,彻底切断循环依赖的可能。
- 隐式Intent方案需保证Action和Scheme的唯一性,避免不同模块跳转冲突。
- 接口方案需确保所有模块的跳转逻辑在Application初始化阶段完成注册,避免跳转时出现未找到的异常。
内容的提问来源于stack exchange,提问作者Rishabh Garg
相关产品推荐
相关产品推荐

