You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.25 10:34:56