Catch missing classes in WorkerFactory (#3744)
When NotificationWorker was moved from ...components.notifications to ...worker. Installing Tusky with this change doesn't remove any future periodic jobs queued under the old class name. So when Class.forName() is called the old class name is not found, and the exception is thrown. Handle this the same way androidx.work.WorkerFactory does -- catch the exception, log it, and return null. Fixes #3740
This commit is contained in:
parent
5327c9f572
commit
eedf6abf91
1 changed files with 18 additions and 3 deletions
|
@ -18,11 +18,13 @@
|
||||||
package com.keylesspalace.tusky.worker
|
package com.keylesspalace.tusky.worker
|
||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
|
import android.util.Log
|
||||||
import androidx.work.ListenableWorker
|
import androidx.work.ListenableWorker
|
||||||
import androidx.work.WorkerFactory
|
import androidx.work.WorkerFactory
|
||||||
import androidx.work.WorkerParameters
|
import androidx.work.WorkerParameters
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
import javax.inject.Provider
|
import javax.inject.Provider
|
||||||
|
import javax.inject.Singleton
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Workers implement this and are added to the map in [com.keylesspalace.tusky.di.WorkerModule]
|
* Workers implement this and are added to the map in [com.keylesspalace.tusky.di.WorkerModule]
|
||||||
|
@ -37,20 +39,33 @@ interface ChildWorkerFactory {
|
||||||
* Creates workers, delegating to each worker's [ChildWorkerFactory.createWorker] to do the
|
* Creates workers, delegating to each worker's [ChildWorkerFactory.createWorker] to do the
|
||||||
* creation.
|
* creation.
|
||||||
*
|
*
|
||||||
* @see [com.keylesspalace.tusky.components.notifications.NotificationWorker]
|
* @see [com.keylesspalace.tusky.worker.NotificationWorker]
|
||||||
*/
|
*/
|
||||||
|
@Singleton
|
||||||
class WorkerFactory @Inject constructor(
|
class WorkerFactory @Inject constructor(
|
||||||
val workerFactories: Map<Class<out ListenableWorker>, @JvmSuppressWildcards Provider<ChildWorkerFactory>>
|
private val workerFactories: Map<Class<out ListenableWorker>, @JvmSuppressWildcards Provider<ChildWorkerFactory>>
|
||||||
) : WorkerFactory() {
|
) : WorkerFactory() {
|
||||||
override fun createWorker(
|
override fun createWorker(
|
||||||
appContext: Context,
|
appContext: Context,
|
||||||
workerClassName: String,
|
workerClassName: String,
|
||||||
workerParameters: WorkerParameters
|
workerParameters: WorkerParameters
|
||||||
): ListenableWorker? {
|
): ListenableWorker? {
|
||||||
val key = Class.forName(workerClassName)
|
val key = try {
|
||||||
|
Class.forName(workerClassName)
|
||||||
|
} catch (e: ClassNotFoundException) {
|
||||||
|
// Class might be missing if it was renamed / moved to a different package, as
|
||||||
|
// periodic work requests from before the rename might still exist. Catch and
|
||||||
|
// return null, which should stop future requests.
|
||||||
|
Log.d(TAG, "Invalid class: $workerClassName", e)
|
||||||
|
null
|
||||||
|
}
|
||||||
workerFactories[key]?.let {
|
workerFactories[key]?.let {
|
||||||
return it.get().createWorker(appContext, workerParameters)
|
return it.get().createWorker(appContext, workerParameters)
|
||||||
}
|
}
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
private const val TAG = "WorkerFactory"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue