首页 > 解决方案 > 设计模块化应用程序 - 导航中的循环依赖问题

问题描述

如您所知,将 Android 应用程序设计为模块是当今 Android 开发领域的流行做法之一。但这种趋势也带来了一些挑战。其中之一是Circular Dependency.

例如,我有一个HomeActivity从主页功能模块打开的导航模块。另外,我必须从产品模块中打开另一个活动,例如 ProductListActivity。

如果我在以下活动之间导航,主页功能必须包括导航模块,并且导航模块应该包括 HomeFeature:

val intent = Intent(activity, HomeActivity::class.java)

这会导致circular dependency问题。

解决此问题的最快解决方案是创建如下意图并在此方法上构建导航系统。

Intent(Intent.ACTION_VIEW).setClassName(PACKAGE_NAME, className)

所以我的问题是,使用这种导航方法我们还会面临哪些其他可能的问题?是否有其他做法来处理模块化 Android 应用程序中的导航?

标签: android

解决方案


这是我的解决方案。这使得显式意图的使用成为可能。您还可以将此方法应用于带有导航组件的单活动应用程序,只需稍作修改。

这是模块 B 的导航对象

object ModuleBNavigator {

    internal lateinit var navigationImpl: ModuleBContract

    fun setNavigationImpl(navigationImpl: ModuleBContract) {
        this.navigationImpl = navigationImpl
    }

    interface ModuleBContract {
        fun navigateModuleA(self: Activity, bundle: Bundle?)
    }
}

这是模块 B 活动

class ModuleBActivity : Activity() {

    companion object {
        private const val BUNDLE = "BUNDLE"
        fun newIntent(context: Context, bundle: Bundle?) = Intent(context, ModuleBActivity::class.java).apply {
            putExtra(BUNDLE, bundle)
        }
    }
}

这是应用程序模块类,用于将导航 impl 注入模块 A 导航对象

class ApplicationModuleApp : Application() {

    // Can also inject with a DI library
    override fun onCreate() {
        super.onCreate()
        ModuleBNavigator.setNavigationImpl(object : ModuleBNavigator.ModuleBContract {
            override fun navigateModuleA(self: Activity, bundle: Bundle?) {
                self.startActivity(ModuleBActivity.newIntent(self, bundle))
            }
        })
    }
}

最后,您可以使用提供的实现从模块 A -> 模块 B 导航

class ModuleAActivity : Activity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        // ... Some code 
        ModuleBNavigator.navigationImpl.navigateModuleA(this, Bundle())
        // .. Some code
    }
}

这种方法避免了循环依赖,您不必再使用隐式意图。希望这可以帮助。


推荐阅读