NoSuchMethodException, создаваемое HiltWorker с дополнительными параметрамиAndroid

Форум для тех, кто программирует под Android
Ответить Пред. темаСлед. тема
Anonymous
 NoSuchMethodException, создаваемое HiltWorker с дополнительными параметрами

Сообщение Anonymous »

Я получаю следующее исключение для двух моих CoroutineWorkers с дополнительными параметрами, введенными Hilt. Этого не происходит для воркеров без дополнительных параметров и происходит только тогда, когда я устанавливаю приложение через APK своей сборкой fastlane. Сборки Android Studio работают отлично. Но мой конвейер сборки использует те же настройки, что и сборки Android Studio. Под работой я подразумеваю, что рабочие ставятся в очередь и не выдают следующее исключение...
Could not instantiate com.example.android.ActivitySyncWorker
java.lang.NoSuchMethodException:
com.example.android.ActivitySyncWorker. [class android.content.Context, class androidx.work.WorkerParameters]
at java.lang.Class.getConstructor0(Class.java:3325)
at java.lang.Class.getDeclaredConstructor(Class.java:3063)
at androidx.work.WorkerFactory.createWorkerWithDefaultFallback(WorkerFactory.java:94)
at androidx.work.impl.WorkerWrapper.runWorker(WorkerWrapper.java:243)
at androidx.work.impl.WorkerWrapper.run(WorkerWrapper.java:144)
at androidx.work.impl.utils.SerialExecutorImpl$Task.run(SerialExecutorImpl.java:96)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:644)
at java.lang.Thread.run(Thread.java:1012)

Внутренняя переменная Hilt mWorkerFactories пуста. Моего работника тогда не найти. Но со сборками Android Studio это не пусто.
Прежде чем я продолжу. Что отличает этот вопрос от других подобных, так это то, что у меня многомодульный проект. Возможно, я что-то упускаю из-за этого.
Это Worker внутри модуля приложения: core-ble
@HiltWorker
class ActivitySyncWorker @AssistedInject constructor(
@Assisted context: Context,
@Assisted params: WorkerParameters,
val bleServiceModule: BleServiceModule,
private val connectionPool: BleConnectionPool,
) : CoroutineWorker(context, params) {
override suspend fun doWork(): Result {
return coroutineScope {
try {
// ...

Result.success()
} catch (exception: Exception) {
SLog.e("[BLE_SYNC] worker error: $exception")
if (runAttemptCount < 2) {
Result.retry()
} else {
Result.failure()
}
}
}
}

companion object {
private const val ACTIVITY_SYNC_WORKER_TAG = "activity_sync"

fun enqueue(context: Context, workManager: WorkManager, workerParams: Data = Data.EMPTY) {
val workRequest = PeriodicWorkRequestBuilder(30, TimeUnit.MINUTES).apply {
addTag(ACTIVITY_SYNC_WORKER_TAG)
setConstraints(
Constraints.Builder()
.setRequiredNetworkType(NetworkType.CONNECTED)
.build()
)
setInputData(
Data.Builder()
.putAll(workerParams)
.build()
)
}.build()

workManager.enqueueUniquePeriodicWork(
/* uniqueWorkName = */ ACTIVITY_SYNC_WORKER_TAG,
/* existingPeriodicWorkPolicy = */ ExistingPeriodicWorkPolicy.CANCEL_AND_REENQUEUE,
/* periodicWork = */ workRequest
)
}

fun stop(context: Context) {
WorkManager.getInstance(context).cancelAllWorkByTag(ACTIVITY_SYNC_WORKER_TAG)
}
}
}

Этот рабочий всегда ставится в очередь, но не имеет дополнительных введенных параметров. Благодаря отражению его можно найти.
@HiltWorker
class RemoteConfigSyncWorker @AssistedInject constructor(
@Assisted context: Context,
@Assisted params: WorkerParameters,
) : CoroutineWorker(context, params) {
override suspend fun doWork(): Result {
return coroutineScope {
try {
// ...

Result.success()
} catch (exception: Exception) {
if (runAttemptCount < 2) {
Result.retry()
} else {
Result.failure()
}
}
}
}

companion object {
private const val REMOTE_CONFIG_SYNC_WORKER_TAG = "remote_config_sync"

fun enqueue(workManager: WorkManager, workerParams: Data = Data.EMPTY) {
val workRequest = PeriodicWorkRequestBuilder(30, TimeUnit.MINUTES).apply {
addTag(REMOTE_CONFIG_SYNC_WORKER_TAG)
setConstraints(
Constraints.Builder()
.setRequiredNetworkType(NetworkType.CONNECTED)
.build()
)
setInputData(
Data.Builder()
.putAll(workerParams)
.build()
)
}.build()

workManager.enqueueUniquePeriodicWork(
/* uniqueWorkName = */ REMOTE_CONFIG_SYNC_WORKER_TAG,
/* existingPeriodicWorkPolicy = */ ExistingPeriodicWorkPolicy.CANCEL_AND_REENQUEUE,
/* periodicWork = */ workRequest
)
}

fun stop(context: Context) {
WorkManager.getInstance(context).cancelAllWorkByTag(REMOTE_CONFIG_SYNC_WORKER_TAG)
}
}
}

Как вы видите в моем манифесте, я удалил инициализатор по умолчанию и добавил свой собственный...





Это новый инициализатор...
@Module
@InstallIn(SingletonComponent::class)
object WorkManagerModule : Initializer {

private var isInitialized = false

@Provides
@Singleton
override fun create(@ApplicationContext context: Context): WorkManager {
if (!isInitialized) { // just in case this gets called twice
val entryPoint = EntryPointAccessors.fromApplication(
context,
HiltWorkerFactoryEntryPoint::class.java
)

val configuration = Configuration.Builder()
.setWorkerFactory(entryPoint.workerFactory())
.setMinimumLoggingLevel(Log.VERBOSE)
.build()

WorkManager.initialize(context, configuration)

isInitialized = true
}

return WorkManager.getInstance(context)
}

override fun dependencies(): MutableList {
return mutableListOf()
}

@EntryPoint
@InstallIn(SingletonComponent::class)
interface HiltWorkerFactoryEntryPoint {
fun workerFactory(): HiltWorkerFactory
}
}

Я делаю это в onCreate моего MultiDexApplication, который находится в :app
AppInitializer.getInstance(this).initializeComponent(WorkManagerModule::class.java)

Мой импорт... (как в :core-ble, так и в :app.
implementation(libs.hilt)
implementation(libs.hilt.work)
implementation(libs.hilt.plugin)
kapt(libs.hilt.compiler)
kapt(libs.hilt.androidx.compiler)
implementation(libs.work.runtime.ktx)
implementation(libs.startup)

hilt = "2.44.2"
hiltAndroidX = "1.1.0"
hiltCompose = "1.0.0"
hiltWork = "1.0.0"
work = "2.9.0"
hiltKapt = "2.35"

hilt-plugin = { group = "com.google.dagger", name = "hilt-android-gradle-plugin", version.ref = "hilt" }
hilt-kapt = { group = "com.google.dagger", name = "hilt-android-compiler", version.ref = "hiltKapt" }
hilt-compiler = { group = "com.google.dagger", name = "hilt-android-compiler", version.ref = "hilt" }
hilt-androidx-compiler = { group = "androidx.hilt", name = "hilt-compiler", version.ref = "hiltAndroidX" }
hilt-work = { group = "androidx.hilt", name = "hilt-work", version.ref = "hiltWork" }
startup = { group = "androidx.startup", name = "startup-runtime", version.ref = "startup" }
hilt = { group = "com.google.dagger", name = "hilt-android", version.ref = "hilt" }
work-runtime = { group = "androidx.work", name = "work-runtime", version.ref = "work" }
work-runtime-ktx = { group = "androidx.work", name = "work-runtime-ktx", version.ref = "work" }

Я также пробовал добавить эти правила ProGuard, но почему они должны работать со сборками Android Studio, а не со сборками APK.
-keepclassmembers class * extends androidx.work.Worker {
public (android.content.Context,androidx.work.WorkerParameters);
}

-keepclassmembers class * extends androidx.work.CoroutineWorker {
public (android.content.Context,androidx.work.WorkerParameters);
}

Это мой модуль рукоятки для одного из параметров WorkManagers. То же самое и с параметрами внутри ProvideBleServiceModule
@Module
@InstallIn(SingletonComponent::class)
object BleServiceModuleModule {

@Singleton
@Provides
fun provideBleServiceModule(
@ApplicationContext context: Context,
sharedPrefHelper: CommonsSharedPrefHelper,
bluetoothAdapterStateModule: BluetoothAdapterStateModule,
userDbService: UserDbService,
bleEvents: BleEvents,
): BleServiceModule = BleServiceModule(
context,
sharedPrefHelper,
bluetoothAdapterStateModule,
userDbService,
bleEvents,
)
}


Подробнее здесь: https://stackoverflow.com/questions/778 ... parameters
Реклама
Ответить Пред. темаСлед. тема

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

  • Похожие темы
    Ответы
    Просмотры
    Последнее сообщение
  • Как создать автоматически создаваемое поле даты/времени в Play! / JPA?
    Гость » » в форуме JAVA
    0 Ответы
    35 Просмотры
    Последнее сообщение Гость
  • FatalException, создаваемое библиотекой protobuf при создании экземпляра сообщения
    Anonymous » » в форуме C++
    0 Ответы
    20 Просмотры
    Последнее сообщение Anonymous
  • @AssistedInject с @HiltWorker не работает после обновления Gradle
    Anonymous » » в форуме Android
    0 Ответы
    11 Просмотры
    Последнее сообщение Anonymous
  • HiltWorker не может внедрить репозиторий
    Anonymous » » в форуме Android
    0 Ответы
    7 Просмотры
    Последнее сообщение Anonymous
  • Медленная производительность запросов при использовании JPQL и Spring с дополнительными параметрами.
    Anonymous » » в форуме JAVA
    0 Ответы
    12 Просмотры
    Последнее сообщение Anonymous

Вернуться в «Android»