Android Dynamic Feature模块:如何实现跨模块双向访问类、Fragment及资源?
访问Android Dynamic Feature模块的类、Fragment及功能
要访问Dynamic Feature(DF)模块内的内容,核心是先确保模块已被下载安装,再通过类加载器或接口化的方式加载目标类/Fragment:
1. 检查并下载DF模块
使用SplitInstallManager处理模块的下载与安装:
val splitInstallManager = SplitInstallManagerFactory.create(context) // 检查模块是否已安装 if (!splitInstallManager.installedModules.contains("your_dynamic_module")) { val request = SplitInstallRequest.newBuilder() .addModule("your_dynamic_module") .build() splitInstallManager.startInstall(request) .addOnSuccessListener { // 模块安装完成,可进行后续访问 } .addOnFailureListener { // 处理下载失败逻辑 } }
2. 访问DF模块内的类
推荐通过公共接口实现解耦,避免直接反射:
- 主应用中定义公共接口:
interface DynamicModuleApi { fun executeFeatureLogic() fun getDynamicFragment(): Fragment }
- DF模块中实现该接口:
class DynamicModuleImpl : DynamicModuleApi { override fun executeFeatureLogic() { // 模块内的业务逻辑 } override fun getDynamicFragment(): Fragment { return DynamicFeatureFragment() } }
- 主应用中加载实现类:
val moduleClassLoader = splitInstallManager.getModuleClassLoader("your_dynamic_module") val implClass = moduleClassLoader.loadClass("com.your.package.DynamicModuleImpl") val api = implClass.newInstance() as DynamicModuleApi // 调用模块功能 api.executeFeatureLogic() // 获取并添加Fragment val dynamicFragment = api.getDynamicFragment() supportFragmentManager.beginTransaction() .replace(R.id.fragment_container, dynamicFragment) .commit()
如果不需要解耦,也可以直接通过类加载器反射实例化类:
val clazz = moduleClassLoader.loadClass("com.your.package.DynamicFeatureClass") val instance = clazz.newInstance() // 通过反射调用方法 val method = clazz.getMethod("featureMethod") method.invoke(instance)
3. 访问DF模块内的Fragment
除了接口返回的方式,也可以直接用Fragment.instantiate加载:
val dynamicFragment = Fragment.instantiate( moduleClassLoader, "com.your.package.DynamicFeatureFragment" ) // 添加到Activity的Fragment容器 supportFragmentManager.beginTransaction() .add(R.id.container, dynamicFragment) .commit()
主应用与Dynamic Feature模块的双向访问实现
完全可以实现双向访问,具体方式如下:
1. 主应用访问DF模块
参考上面的步骤,核心是通过SplitInstallManager确保模块已安装,再通过类加载器或接口加载内容。
2. DF模块访问主应用
DF模块默认依赖主应用的base模块(或主应用本身),因此可以直接引用主应用中public修饰的类、方法、资源:
- 主应用中的公共工具类:
object MainAppUtils { fun doMainAppTask() { // 主应用的公共逻辑 } }
- DF模块中直接调用:
import com.your.mainapp.MainAppUtils class DynamicFeatureFragment : Fragment() { override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) // 调用主应用的方法 MainAppUtils.doMainAppTask() // 访问主应用的资源 val mainAppString = getString(R.string.main_app_string) } }
注意事项
- 双向访问时,尽量通过公共接口/抽象类交互,避免直接依赖具体实现,降低模块间耦合。
- DF模块只能访问主应用暴露的public内容,无法访问主应用的私有类、内部类或私有方法。
- 主应用访问DF模块前,必须确保模块已下载安装,否则会抛出
ClassNotFoundException。
内容的提问来源于stack exchange,提问作者Vijay Rathod
相关产品推荐
相关产品推荐

