Sunday 12 January 2020

RxWorker being called multiple times even when not scheduled?

I have followed this article on how to do DI on WorkManagers, so I have this factory:

 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)
        }

    }
}

And this is my module:

@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


}

Which is part of my Application Component. Then on my Application class I do this:

@Inject lateinit var myWorkerFactory: MyWorkerFactory

private fun setupWorkerFactory() {
        WorkManager.initialize(
                this,
                Configuration.Builder()
                        .setWorkerFactory(myWorkerFactory)
                        .build()
        )
    }

My Worker class:

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)
        }
    }


}

Now even if I dont schedule this worker at all, my log is printing Parcel poll worker $this here trying to do some work! with different instances multiple times (sometimes 3, sometimes 6)! Also the lines of the actual work get printed multiple times on startup of the app:

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

How is this even possible? I checked the implementation of RxWorker and it shouldn print at least the work itself until its started (i.e. someone subscribes to it)

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;
}

I'm lost here on what could be happening. Code is open source and can be checked here



from RxWorker being called multiple times even when not scheduled?

No comments:

Post a Comment