如何在Android多模块项目的usecase模块中引入Context?
解决多模块项目中UseCase无法引入Context的问题
核心问题分析
你的usecase模块当前使用java-library和kotlin-jvm插件,属于纯JVM模块,这类模块无法直接访问Android系统API(比如Context),也不能正确解析AndroidX依赖,这就是你遇到依赖报错和无法引入Context的根本原因。
方案一:将usecase转为Android库模块
直接把模块改为Android库,即可正常使用Android API和依赖:
- 修改模块build.gradle的插件配置
替换原插件:
plugins { id 'com.android.library' id 'org.jetbrains.kotlin.android' }
- 添加Android模块核心配置
替换原java块,添加Android编译相关配置:
android { namespace "com.yourpackage.usecase" // 替换为你的模块包名 compileSdk 34 // 可根据项目需求调整版本 defaultConfig { minSdk 21 // 匹配项目的minSdk版本 targetSdk 34 } compileOptions { sourceCompatibility JavaVersion.VERSION_1_8 targetCompatibility JavaVersion.VERSION_1_8 } kotlinOptions { jvmTarget = "1.8" } }
- 修正依赖并同步项目
在dependencies块中添加AndroidX核心依赖(仅需core-ktx即可,无需appcompat):
dependencies { implementation project(path: ':data') implementation project(path: ':entity') implementation 'androidx.core:core-ktx:1.7.0' implementation 'io.reactivex.rxjava3:rxandroid:3.0.0' implementation 'com.squareup.retrofit2:converter-gson:2.9.0' implementation 'com.squareup.retrofit2:adapter-rxjava2:2.9.0' implementation 'com.squareup.okhttp3:logging-interceptor:5.0.0-alpha.2' implementation 'io.reactivex.rxjava3:rxkotlin:3.0.0' implementation 'com.github.akarnokd:rxjava3-retrofit-adapter:3.0.0' }
同步项目后,就能正常引入android.content.Context了。
方案二:依赖倒置(更符合分层架构)
若希望usecase保持纯JVM模块(遵循依赖倒置原则,不依赖Android层),可将需Context的逻辑封装为接口:
- 在usecase模块定义接口
interface ImageFileConverter { fun getImageFileFromUri(uri: Uri): File? }
- 修改UploadImageUseCase构造函数
class UploadImageUseCase( private val requestCreationRepository: DocumentRepository, private val imageFileConverter: ImageFileConverter ) : UseCase<UploadImageAction, UploadImageResult> { override fun apply(upstream: Observable<UploadImageAction>): ObservableSource<UploadImageResult> { return upstream.flatMap { action -> val imageFile = imageFileConverter.getImageFileFromUri(action.uri[0]) ?: run { return@flatMap Observable.just(UploadImageResult.Error(IllegalArgumentException("无法获取图片文件"))) } val requestFile = imageFile.asRequestBody("image/*".toMediaTypeOrNull()) val filePart = MultipartBody.Part.createFormData("file", imageFile.name, requestFile) requestCreationRepository.uploadImage(action, filePart).toObservable().map { result -> result.fold(onSuccess = { UploadImageResult.Successful(it.data!!) }, onFailure = { UploadImageResult.Error(it) }) }.startWithItem(UploadImageResult.Loading) } } }
- 在Android模块实现接口
在App模块(或其他Android模块)中实现接口并传入Context:
class AndroidImageFileConverter(private val context: Context) : ImageFileConverter { override fun getImageFileFromUri(uri: Uri): File? { // 实现你的图片文件转换逻辑,使用context return // 返回转换后的File } }
- 注入UseCase时传入实现类
在依赖注入环节(如ViewModel或DI容器),传入Android端的实现实例:
val uploadImageUseCase = UploadImageUseCase( requestCreationRepository, AndroidImageFileConverter(appContext) )
这种方式让usecase模块保持独立,不依赖Android环境,更利于单元测试和模块解耦。
内容的提问来源于stack exchange,提问作者Ahmet Yılmaz
相关产品推荐
相关产品推荐

