We are using Workmanager to perform Network and background data sync task in our application and as per our regular code review sessions, we found that we can refactor and rewrite code so we don’t need one worker in our app.
After deleting the worker, we installed the fresh application and tested and everything was working fine. One day, our crash monitoring and reporting team told us that there are crash reported on Google play console related to the “Class not found for com.xxxx.xxxx.BackgroundDbSyncWorker” in our application.
After testing and debugging, we found that it was happening for the worker which we have deleted in release worker. Since. it was a periodic worker which was set to perform background sync after every 24 hours so entry for this task was present inside the
Workmanager DB and when all constraint matched
Workerfactory tried to instantiate the instance of the
“com.xxxx.xxxx.BackgroundDbSyncWorker” but it didn’t found the
BackgroundDbSyncWorker in our application so it threw Class not found exception.
Default Worker factory, will handle this scenario very well without crashing the Job but we were using custom worker factory for worker creation.
Sample of our Custom worker factory implementation:
class DMWorkerFactory : WorkerFactory() {
override fun createWorker(appContext: Context, workerClassName: String, workerParameters:
WorkerParameters): ListenableWorker? {
val workerClass = Class.forName(workerClassName).asSubclass(ListenableWorker::class.java)
val constructor = workerClass.getDeclaredConstructor(Context::class.java, WorkerParameters::class.java)
return constructor.newInstance(appContext, workerParameters)
}
}
In our above sample code, “com.xxxx.xxxx.BackgroundDbSyncWorker” will be passed to the createWorker method as workerClassName parameter but implementation of “com.xxxx.xxxx.BackgroundDbSyncWorker” class will not exist in our application so it will throw Class not found exception.
To overcome this issue, we must handle this scenario inside the catch block and must return null as per the google docs.
class DMWorkerFactory : WorkerFactory() {
override fun createWorker(appContext: Context, workerClassName: String, workerParameters: WorkerParameters): ListenableWorker? {
try {
val workerClass = Class.forName(workerClassName).asSubclass(ListenableWorker::class.java)
val constructor = workerClass.getDeclaredConstructor(Context::class.java, WorkerParameters::class.java)
return constructor.newInstance(appContext, workerParameters)
} catch (e: ClassNotFoundException) {
return null
}
}
}
Comments
Post a Comment