如何在AndroidStudio中使用Dagger2和Kotlin在其他项目模块中实现接口库

我想在AndroidStudio中可以有2个不同的被动接口实现在其他工程模块中获取用户位置。

所以要具体它可以通过使用GMS,或只是本地Android的LocationManager。

这是我的存储库接口:

interface RxLocationRepository { @SuppressLint("MissingPermission") fun onLocationUpdate(): Observable<Location> fun stopLocationUpdates() } 

所以现在,我在这里实现这个接口,在AndroidStudio中的同一个项目模块中的类:

 class RxLocationRepositoryImpl(val reactiveLocationProvider: ReactiveLocationProvider, val reactiveLocationRequest: LocationRequest, val isUsingLocationNativeApi: Boolean, val locationManager: LocationManager, val geoEventsDistanceMeters: Int, val geoEventsIntervalSeconds: Int ) : RxLocationRepository { var locationToPopulate: Location = Location(LocationManager.GPS_PROVIDER) lateinit var mLocationCallbackNativeApi: LocationListener private val subject: BehaviorSubject<Location> = BehaviorSubject.createDefault(locationToPopulate) var locationEmitter: Observable<Location> = subject.hide() init { configureEmitter() } @SuppressLint("MissingPermission") private fun configureEmitter(){ if (!isUsingLocationNativeApi) locationEmitter = reactiveLocationProvider.getUpdatedLocation(reactiveLocationRequest) else{ configureNativeLocationEmitter() } } @SuppressLint("MissingPermission") private fun configureNativeLocationEmitter() { mLocationCallbackNativeApi = object : LocationListener { override fun onLocationChanged(location: Location) { subject.onNext(location) } override fun onStatusChanged(provider: String, status: Int, extras: Bundle) {} override fun onProviderEnabled(provider: String) {} override fun onProviderDisabled(provider: String) {} } try { locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, (geoEventsIntervalSeconds * 1000).toLong(), geoEventsDistanceMeters.toFloat(), mLocationCallbackNativeApi, Looper.getMainLooper()) } catch (ignored: IllegalArgumentException) { ignored.printStackTrace() } try { locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, (geoEventsIntervalSeconds * 1000).toLong(), geoEventsDistanceMeters.toFloat(), mLocationCallbackNativeApi, Looper.getMainLooper()) } catch (ignored: IllegalArgumentException) { ignored.printStackTrace() } } @SuppressLint("MissingPermission") override fun onLocationUpdate(): Observable<Location> { return locationEmitter } override fun stopLocationUpdates() { if(isUsingLocationNativeApi) locationManager.removeUpdates(mLocationCallbackNativeApi) } } 

所以一切都很好,但现在我想在不同的项目模块(所以我不需要在Gradle中有gms依赖项)gms实现,并且本地实现到Android Studio中的其他模块。

AndroidStudio项目的最终结构将类似于location_core,location_gms,location_native。

location_core一定不知道location_gms和native,我猜想它们是相反的 – 它们将依赖于location_core。

所以现在,ii只有location_core项目模块和一个LocationClient类,它将提供上下文:

 class LocationClient @Inject constructor(val nexoLocationManager: NexoLocationManager){ companion object { private var locationClient: LocationClient? = null fun obtainLocationClient(context: Context): LocationClient{ val result = locationClient ?: DaggerLocationComponent .builder() .context(context) .build() .locationClient() locationClient = result return result } } } 

它使用了一些Dagger组件,为他提供了所有不同对象的实现。 所以我想移动这个LocationClient或者在location_core项目模块中将其抽象化,并在AndroidStudio的每个location_gms和location_native项目模块中移动它的实现。

所以每个LocationClient类将提供这个RxRepository的不同实现。 现在在每个location_gms和location_native项目模块中,我只有实现类,它实现了存储库rxLocationRepository(我从上面写的实现移动)在自己的方式。

问题是我不知道如何用匕首来管理所有这些。 现在我在我的location_core中使用了这样的Dagger,这里是LocationComponent:

 @Singleton @Component(modules = arrayOf(LocationModule::class)) interface LocationComponent{ fun locationClient(): LocationClient @Component.Builder interface Builder { @BindsInstance fun context(context: Context): Builder fun build(): LocationComponent } } 

和它的模块:

 @Module class LocationModule { //some stuff @Provides @Singleton fun providesRxLocationRepository( reactiveLocationProvider: ReactiveLocationProvider, reactiveLocationRequest: LocationRequest, @Named("CONFIG_LOCATION_USE_NATIVE_API")isUsingLocationNativeApi: Boolean, locationManager: LocationManager, @Named("CONFIG_LOCATION_GEO_EVENTS_DISTANCE_METERS")geoEventsDistanceMeters: Int, @Named("CONFIG_LOCATION_GEO_EVENTS_INTERVAL_SECONDS")geoEventsIntervalSeconds: Int ): RxLocationRepository = RxLocationRepositoryImpl( reactiveLocationProvider, reactiveLocationRequest, isUsingLocationNativeApi, locationManager, geoEventsDistanceMeters, geoEventsIntervalSeconds) //some other stuff } 

那么如何在每个模块中写入实际的LocationClient – location_gms和location_native? 如何使用Dagger提供每个location_gms和location_native项目模块中的rxLocationRepository的实现,这样我就可以在我的location_core模块中使用接口RxLocationRepository,不用担心它的实现,因为它会在每个项目模块?

当然,我必须指出,这3个模块从来没有在一起,我猜,这将是每个build_variant 2模块我猜。 所以我必须摆脱location_core项目模块build.gradle中的谷歌服务依赖项。

在这里输入图像描述