[ad_1]
Modularization is a great tool for building an app at scale, however care must be taken to ensure that resources shared between modules are properly instantiated. WorkManager
provides a default configuration that is applied on app start up. This is often convenient, but in a modularized app where different modules often have different dependencies, WorkManager’s
default configuration may not be enough. This blog post details how we set up WorkManager
for use in the multi module Now in Android app.
WorkManager
exists as a singleton instance. To provide custom configuration for this instance in a single module app, you can implement a Configuration.Provider
that provides parameters for the Executor
used to perform work. You can also implement a WorkerFactory
to aid in dependency injection when using WorkManager
with Hilt.
Things get more nuanced in a multi-module app. Which module should be responsible for configuring the WorkManager
instance? If such a module exists, wouldn’t it need to depend on all modules that need workers? Wouldn’t that break the “low cohesion” principle when modularizing apps? It would, so instead, we lean on another software engineering principle: delegation.
Creating a DelegatingWorker
WorkManager
WorkerFactory
instances can create Worker
instances at runtime given:
When you couple this with Hilt entry points, it becomes possible to dynamically delegate to Worker
instances lazily without having to implement the Configuration.Provider
in a central location. The skeleton for such an implementation follows:
The above code determines what Worker
the app should delegate to. To do so, it reads the fully qualified name of the Worker
class from the WorkerParameters
. Once it has that, it takes the HiltWorkerFactoryEntryPoint
from the application Context
and uses it to instantiate the given Worker
.
See the following snippet for an example of a utility method you could use to pass the fully qualified name of the worker to the DelegatingWorker
via the WorkerParameters
:
To use the above function, create a WorkRequest
targeting the DelegatingWorker
, and then add any other metadata needed for the work in the delegated Worker
. In the snippet to follow, the delegated Worker
is the SyncWorker
.
Finally, enqueue the work as usual:
Use of a DelegatingWorker
instance is useful in more than just multi-module apps. It is also useful for libraries who need to use WorkManager
but cannot pass their dependencies easily to the apps that depend on them.
A useful rule of thumb is, if you do not have convenient access to the Application
instance in app and you need to call on WorkManager
, use a delegating worker to lazily create your actual Worker
with the necessary WorkerFactory
.
[ad_2]
Source link
Leave a Reply