我在使用 Kodein 实现 android WorkManager 时遇到了麻烦。我想使用 WorkManager 来跟踪后台位置更新,并定期向我的服务器发送发布请求以及用户的新位置。
我已经看到了多种使用 Dagger2 实现此功能的方法,但我想知道 kodein 是否有类似的解决方案?
这是我得到的错误:
2019-09-23 12:44:06.690 17462-17500/com.rainparrot.app E/WM-WorkerFactory: Could not instantiate com.rainparrot.app.utility.TrackLocationWorker
java.lang.NoSuchMethodException: <init> [class android.content.Context, class androidx.work.WorkerParameters]
at java.lang.Class.getConstructor0(Class.java:2204)
at java.lang.Class.getDeclaredConstructor(Class.java:2050)
at androidx.work.WorkerFactory.createWorkerWithDefaultFallback(WorkerFactory.java:96)
at androidx.work.impl.WorkerWrapper.runWorker(WorkerWrapper.java:228)
at androidx.work.impl.WorkerWrapper.run(WorkerWrapper.java:127)
at androidx.work.impl.utils.SerialExecutor$Task.run(SerialExecutor.java:91)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1133)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:607)
at java.lang.Thread.run(Thread.java:761)
2019-09-23 12:44:06.690 17462-17500/com.rainparrot.app E/WM-WorkerWrapper: Could not create Worker com.rainparrot.app.utility.TrackLocationWorker
2019-09-23 12:44:06.830 17462-17462/com.rainparrot.app D/MainActivity$onCreate: Work Manager Status: FAILED
这是我的主应用程序文件,其中包含我所有的 kodein 绑定:
override val kodein = Kodein.lazy {
import(androidXModule(this@ForecastApplication))
val prefs = PreferenceManager.getDefaultSharedPreferences(this@ForecastApplication)
bind<ICurrentWeatherDao>() with singleton { CurrentWeatherDao(prefs) }
bind<IConnectivityInterceptor>() with singleton { ConnectivityInterceptor(instance()) }
bind() from singleton { ApiService(instance()) }
bind<IWeatherNetworkDataSource>() with singleton { WeatherNetworkDataSource(instance(), instance()) }
bind<ILocationService>() with singleton { LocationService() }
bind<IForecastRepository>() with singleton { ForecastRepository(instance(), instance(), instance(), instance(), instance(), instance()) }
bind() from provider { LocationRepository(instance()) }
bind() from provider { TrackLocationWorker(instance(), instance(), instance()) }
bind() from provider { WeatherViewModelFactory(instance()) }
}
TrackLocationWorker:
class TrackLocationWorker (
private val repository: LocationRepository,
context: Context,
workerParams: WorkerParameters
) : Worker(context, workerParams){
override fun doWork(): Result {
return try {
repository.getLocation()
Result.success()
} catch (e: Exception) {
Timber.e(e, "Failure in doing work")
Result.failure()
}
}
}
MainActivity 实例化:
fun getFromLocation() = if (isGPSEnabled()) forecastRepository.trackLocation() else forecastRepository.locationSetup()
预测存储库设置:
override fun locationSetup() {
enableLocation.value = Response.loading()
LocationServices.getSettingsClient(application)
.checkLocationSettings(
LocationSettingsRequest.Builder()
.addLocationRequest(locationRequest())
.setAlwaysShow(true)
.build())
.addOnSuccessListener { enableLocation.value = Response.success(true) }
.addOnFailureListener {
Timber.e(it, "Gps not enabled")
enableLocation.value = Response.error(it)
}
}
override fun trackLocation() {
val locationWorker = PeriodicWorkRequestBuilder<TrackLocationWorker>(15, TimeUnit.MINUTES).addTag(LOCATION_WORK_TAG).build()
WorkManager.getInstance(this@ForecastRepository.context).enqueueUniquePeriodicWork(LOCATION_WORK_TAG, ExistingPeriodicWorkPolicy.KEEP, locationWorker)
}