我遵循了这关于如何在WorkManagers上执行DI的文章,所以我有一个工厂:
class MyWorkerFactory @Inject constructor(
val workerFactories: Map<Class<out ListenableWorker>, @JvmSuppressWildcards Provider<ChildWorkerFactory>>
) : WorkerFactory() {
override fun createWorker(
appContext: Context,
workerClassName: String,
workerParameters: WorkerParameters
): ListenableWorker? {
val foundEntry = workerFactories.entries.find { Class.forName(workerClassName).isAssignableFrom(it.key) }
return if (foundEntry != null) {
val factoryProvider = foundEntry.value
factoryProvider.get().create(appContext, workerParameters)
} else {
val workerClass = Class.forName(workerClassName).asSubclass(ListenableWorker::class.java)
val constructor = workerClass.getDeclaredConstructor(Context::class.java, WorkerParameters::class.java)
constructor.newInstance(appContext, workerParameters)
}
}
}这是我的模块:
@Retention(AnnotationRetention.RUNTIME)
@MapKey
annotation class WorkerKey(val value: KClass<out ListenableWorker>)
@Module
abstract class ParcelPollModule {
@Binds
@IntoMap
@WorkerKey(ParcelPollWorker::class)
internal abstract fun bindMyWorkerFactory(worker: ParcelPollWorker.Factory): ChildWorkerFactory
}这是我的应用程序组件的一部分。然后,在我的应用程序类中,我执行以下操作:
@Inject lateinit var myWorkerFactory: MyWorkerFactory
private fun setupWorkerFactory() {
WorkManager.initialize(
this,
Configuration.Builder()
.setWorkerFactory(myWorkerFactory)
.build()
)
}我的工人阶级:
class ParcelPollWorker constructor(val parcelRepository: LocalParcelRepository,
val correosRepository: CorreosRepository,
appContext: Context, workerParams: WorkerParameters) : RxWorker(appContext, workerParams) {
override fun createWork(): Single<Result> {
Timber.w("Parcel poll worker $this here trying to do some work!")
return parcelRepository.getParcels()
.flatMapIterable {
it
}
.map {
Timber.d("Parcel poll checking parcel with code ${it.code}")
// correosRepository.getParcelStatus(it.code)
}
.toList()
.map { Result.success() }
.onErrorReturn {
Result.failure()
}
}
class Factory @Inject constructor(
val myRepository: LocalParcelRepository,
val networkService: CorreosRepository
) : ChildWorkerFactory {
override fun create(appContext: Context, params: WorkerParameters): ListenableWorker {
return ParcelPollWorker(myRepository, networkService, appContext, params)
}
}
}现在,即使我根本没有调度这个工作人员,我的日志也是用不同的实例多次打印Parcel poll worker $this here trying to do some work! (有时3,有时6)!此外,在启动应用程序时,实际工作的行会多次打印:
2020-01-08 08:37:40.892 7011-7011/com.myapp.android W/ParcelPollWorker: Parcel poll worker com.myapp.service.worker.ParcelPollWorker@c1f5d23 here trying to do some work!
2020-01-08 08:37:40.923 7011-7011/com.myapp.android W/ParcelPollWorker: Parcel poll worker com.myapp.service.worker.ParcelPollWorker@c80a87f here trying to do some work!
2020-01-08 08:37:40.924 7011-7011/com.myapp.android W/ParcelPollWorker: Parcel poll worker com.myapp.service.worker.ParcelPollWorker@85b9895 here trying to do some work!
2020-01-08 08:37:40.945 7011-7113/com.myapp.android D/ParcelPollWorker$createWork: Parcel poll checking parcel with code 63583511008898301184149
2020-01-08 08:37:40.946 7011-7113/com.myapp.android D/ParcelPollWorker$createWork: Parcel poll checking parcel with code 800692129
2020-01-08 08:37:40.946 7011-7113/com.myapp.android D/ParcelPollWorker$createWork: Parcel poll checking parcel with code PQ5HG70200028570115706M
2020-01-08 08:37:40.946 7011-7113/com.myapp.android D/ParcelPollWorker$createWork: Parcel poll checking parcel with code UX6CFH0459568380108027M
2020-01-08 08:37:40.947 7011-7113/com.myapp.android D/ParcelPollWorker$createWork: Parcel poll checking parcel with code 6307253297994985
2020-01-08 08:37:40.949 7011-7113/com.myapp.android D/ParcelPollWorker$createWork: Parcel poll checking parcel with code 63583560022440001250051
2020-01-08 08:37:40.954 7011-7102/com.myapp.android D/ParcelPollWorker$createWork: Parcel poll checking parcel with code 63583511008898301184149
2020-01-08 08:37:40.955 7011-7102/com.myapp.android D/ParcelPollWorker$createWork: Parcel poll checking parcel with code 800692129
2020-01-08 08:37:40.955 7011-7102/com.myapp.android D/ParcelPollWorker$createWork: Parcel poll checking parcel with code PQ5HG70200028570115706M
2020-01-08 08:37:40.955 7011-7101/com.myapp.android D/ParcelPollWorker$createWork: Parcel poll checking parcel with code 63583511008898301184149
2020-01-08 08:37:40.955 7011-7101/com.myapp.android D/ParcelPollWorker$createWork: Parcel poll checking parcel with code 800692129
2020-01-08 08:37:40.955 7011-7102/com.myapp.android D/ParcelPollWorker$createWork: Parcel poll checking parcel with code UX6CFH0459568380108027M
2020-01-08 08:37:40.955 7011-7101/com.myapp.android D/ParcelPollWorker$createWork: Parcel poll checking parcel with code PQ5HG70200028570115706M
2020-01-08 08:37:40.956 7011-7101/com.myapp.android D/ParcelPollWorker$createWork: Parcel poll checking parcel with code UX6CFH0459568380108027M
2020-01-08 08:37:40.956 7011-7102/com.myapp.android D/ParcelPollWorker$createWork: Parcel poll checking parcel with code 6307253297994985
2020-01-08 08:37:40.956 7011-7102/com.myapp.android D/ParcelPollWorker$createWork: Parcel poll checking parcel with code 63583560022440001250051
2020-01-08 08:37:40.956 7011-7101/com.myapp.android D/ParcelPollWorker$createWork: Parcel poll checking parcel with code 6307253297994985
2020-01-08 08:37:40.956 7011-7101/com.myapp.android D/ParcelPollWorker$createWork: Parcel poll checking parcel with code 63583560022440001250051这怎么可能?我检查了RxWorker的实现,它应该至少打印工作本身,直到它开始(即有人订阅它)
public RxWorker(@NonNull Context appContext, @NonNull WorkerParameters workerParams) {
super(appContext, workerParams);
}
@NonNull
@Override
public ListenableFuture<Result> startWork() {
mSingleFutureObserverAdapter = new SingleFutureAdapter<>();
final Scheduler scheduler = getBackgroundScheduler();
createWork()
.subscribeOn(scheduler)
// observe on WM's private thread
.observeOn(Schedulers.from(getTaskExecutor().getBackgroundExecutor()))
.subscribe(mSingleFutureObserverAdapter);
return mSingleFutureObserverAdapter.mFuture;
}我在这里迷失在可能发生的事情上。代码是开放源码的,可以检查这里。
持有该工人的班级:
class ParcelListActivity : BaseActivity() {
@Inject
lateinit var myWorkerFactory: MyWorkerFactory
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
setSupportActionBar(toolbar)
supportActionBar?.setDisplayShowTitleEnabled(true)
fab.setOnClickListener {
startActivityForResult(CreateActivity.newIntent(this),
REQ_CREATE_PARCEL)
}
val constraints = Constraints.Builder()
.setRequiredNetworkType(NetworkType.CONNECTED)
.build()
val uploadWorker = PeriodicWorkRequest.Builder(
ParcelPollWorker::class.java, 15, TimeUnit.MINUTES)
.setConstraints(constraints)
.build()
WorkManager.getInstance(this).enqueue(uploadWorker)
}
...
}“艺术建议”之后的变化:
private fun initWorker() {
val constraints = Constraints.Builder()
.setRequiredNetworkType(NetworkType.CONNECTED)
.build()
val uploadWorker = PeriodicWorkRequest.Builder(
ParcelPollWorker::class.java, 15, TimeUnit.MINUTES)
.setConstraints(constraints)
.build()
WorkManager.getInstance(this).cancelAllWork()
WorkManager.getInstance(this).enqueueUniquePeriodicWork(PARCEL_CHECKER_WORKREQUEST, ExistingPeriodicWorkPolicy.REPLACE, uploadWorker)
}发布于 2020-01-17 09:17:31
1.注意到,根据RxWorker的源代码
@NonNull
@Override
public ListenableFuture<Result> startWork() {
mSingleFutureObserverAdapter = new SingleFutureAdapter<>();
final Scheduler scheduler = getBackgroundScheduler();
createWork()
.subscribeOn(scheduler)
// observe on WM's private thread
.observeOn(Schedulers.from(getTaskExecutor().getBackgroundExecutor()))
.subscribe(mSingleFutureObserverAdapter);
return mSingleFutureObserverAdapter.mFuture;
}工作的执行是在调用subscribe对象的Single方法时开始的。所以你的说法是不正确的:
这怎么可能?我检查了RxWorker的实现,它应该至少打印工作本身,直到它开始(即有人订阅它)
2.大概是在您的开发过程中的某个时刻,您在ParcelListActivity.onCreate方法中使用了员工队列代码,并且您多次打开了该活动,因此多次对定期工作人员进行了排队,WorkManager将此工作保留在其内部数据库中,现在根据您的预请求配置启动该工作。
要解决这个问题,可以使用cancelAllWork方法。但是,正如docs声称的那样,这个方法应该非常谨慎地使用!一般情况下,定期工作需要更精确的处理。例如,您可以对工作请求进行指定一个标记,然后可以使用cancelAllWorkByTag方法取消工作。此外,您还可以考虑使用以独特的方式展开你的工作 --在大多数情况下,这是更合适的方法。
https://stackoverflow.com/questions/59641421
复制相似问题