HiltWorker не может внедрить репозиторийAndroid

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

Сообщение Anonymous »

Я пытаюсь создать PeriodicWorkRequestBuilder, который выполняет запрос через репозиторий Firestore, а затем отправляет уведомление. Но рабочий процесс выходит из строя сразу при запуске.
Фрагмент LogCat:

Код: Выделить всё

Scheduling work ID faacd85c-18fb-43a0-950c-55473ed2de3aJob ID 42
Starting work for faacd85c-18fb-43a0-950c-55473ed2de3a
Processor: processing WorkGenerationalId(workSpecId=faacd85c-18fb-43a0-950c-55473ed2de3a, generation=0)
Compat change id reported: 263076149; UID 10218; state: ENABLED
Could not instantiate com.amel.faerntourism.worker.DailyInterestingPlaceNotificationWorker
java.lang.NoSuchMethodException: com.amel.faerntourism.worker.DailyInterestingPlaceNotificationWorker. [class android.content.Context, class androidx.work.WorkerParameters]
at java.lang.Class.getConstructor0(Class.java:3395)
at java.lang.Class.getDeclaredConstructor(Class.java:3077)
at androidx.work.WorkerFactory.createWorkerWithDefaultFallback$fallbackToReflection(WorkerFactory.kt:87)
at androidx.work.WorkerFactory.createWorkerWithDefaultFallback(WorkerFactory.kt:96)
at androidx.work.impl.WorkerWrapper.runWorker(WorkerWrapper.kt:234)
at androidx.work.impl.WorkerWrapper.access$runWorker(WorkerWrapper.kt:67)
at androidx.work.impl.WorkerWrapper$launch$1$resolution$1.invokeSuspend(WorkerWrapper.kt:98)
at androidx.work.impl.WorkerWrapper$launch$1$resolution$1.invoke(Unknown Source:8)
at androidx.work.impl.WorkerWrapper$launch$1$resolution$1.invoke(Unknown Source:4)
at kotlinx.coroutines.intrinsics.UndispatchedKt.startUndispatchedOrReturn(Undispatched.kt:42)
at kotlinx.coroutines.BuildersKt__Builders_commonKt.withContext(Builders.common.kt:164)
at kotlinx.coroutines.BuildersKt.withContext(Unknown Source:1)
at androidx.work.impl.WorkerWrapper$launch$1.invokeSuspend(WorkerWrapper.kt:98)
at androidx.work.impl.WorkerWrapper$launch$1.invoke(Unknown Source:8)
at androidx.work.impl.WorkerWrapper$launch$1.invoke(Unknown Source:4)
at androidx.work.ListenableFutureKt$launchFuture$1$2.invokeSuspend(ListenableFuture.kt:42)
at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)
at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:101)
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)
Could not create Worker com.amel.faerntourism.worker.DailyInterestingPlaceNotificationWorker
androidx.work.impl.background.systemalarm.RescheduleReceiver enabled
androidx.work.impl.background.systemalarm.RescheduleReceiver disabled
Если я удалю зависимость репозитория из работника конструктора (и просто оставьте dowork () {result.success ()}) , он показывает успех, по крайней мере.
Вот несколько фрагментов: < /p>
Работник: < /p>

Код: Выделить всё

package com.amel.faerntourism.worker

import android.content.Context
import androidx.hilt.work.HiltWorker
import androidx.work.CoroutineWorker
import androidx.work.WorkerParameters
import com.amel.faerntourism.data.FireStoreRepository
import com.amel.faerntourism.worker.makeInterestingPlaceNotification
import dagger.assisted.Assisted
import dagger.assisted.AssistedInject

@HiltWorker
class DailyInterestingPlaceNotificationWorker @AssistedInject constructor(
@Assisted context: Context,
@Assisted workerParams: WorkerParameters,
private val fireStoreRepository: FireStoreRepository
) : CoroutineWorker(context, workerParams) {

override suspend fun doWork(): Result {
val placesResult = fireStoreRepository.getPlaces()

placesResult.onSuccess { places ->
if (places.isNotEmpty()) {
val randomPlace = places.random()

makeInterestingPlaceNotification(randomPlace, applicationContext)

return Result.success()
} else {
return Result.failure()
}
}.onFailure {
return Result.failure()
}
return Result.failure()
}
}
Создание уведомлений:

Код: Выделить всё

package com.amel.faerntourism.worker

import android.annotation.SuppressLint
import android.app.NotificationChannel
import android.app.NotificationManager
import android.content.Context
import android.os.Build
import androidx.annotation.RequiresApi
import androidx.core.app.NotificationCompat
import androidx.core.app.NotificationManagerCompat
import com.amel.faerntourism.CHANNEL_ID
import com.amel.faerntourism.NOTIFICATION_ID
import com.amel.faerntourism.NOTIFICATION_TITLE
import com.amel.faerntourism.R
import com.amel.faerntourism.VERBOSE_NOTIFICATION_CHANNEL_DESCRIPTION
import com.amel.faerntourism.VERBOSE_NOTIFICATION_CHANNEL_NAME
import com.amel.faerntourism.data.model.Place

@SuppressLint("MissingPermission")
fun makeInterestingPlaceNotification(
place: Place,
context: Context
) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) createNotificationChannel(context)

val builder = NotificationCompat.Builder(context, CHANNEL_ID)
.setSmallIcon(R.drawable.landscape)
.setContentTitle(NOTIFICATION_TITLE)
.setContentText(place.name)
.setPriority(NotificationCompat.PRIORITY_HIGH)
.setAutoCancel(true)
.build()

NotificationManagerCompat.from(context).notify(NOTIFICATION_ID, builder)
}

@RequiresApi(Build.VERSION_CODES.O)
private fun createNotificationChannel(context: Context) {
val importance = NotificationManager.IMPORTANCE_HIGH
val channel = NotificationChannel(
CHANNEL_ID,
VERBOSE_NOTIFICATION_CHANNEL_NAME,
importance
)
channel.description = VERBOSE_NOTIFICATION_CHANNEL_DESCRIPTION

val notificationManager =
context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager?

notificationManager?.createNotificationChannel(channel)
}
Репозиторий Firestore:

Код: Выделить всё

package com.amel.faerntourism.data

import com.amel.faerntourism.data.model.Article
import com.amel.faerntourism.data.model.Place
import com.google.firebase.firestore.FirebaseFirestore
import com.google.firebase.firestore.toObject
import kotlinx.coroutines.tasks.await
import javax.inject.Inject

interface FireStoreRepository {
suspend fun getPlaces(): Result
suspend fun getArticles(): Result

suspend fun getPlace(id: String): Result
suspend fun getArticle(id: String): Result
}

class FireStoreRepositoryImpl @Inject constructor(
private val fireStore: FirebaseFirestore
) : FireStoreRepository {
override suspend fun getPlaces(): Result  =
try {
val snapshot = fireStore.collection(PLACES_COLLECTION).get().await()

val places = snapshot.documents.map { document ->
document.toObject()?.copy(id = document.id) ?: Place()
}

Result.success(places)
} catch (e: Exception) {
Result.failure(e)
}

override suspend fun getArticles(): Result =
try {
val snapshot = fireStore.collection(ARTICLES_COLLECTION).get().await()

val articles = snapshot.documents.map { document ->
document.toObject()?.copy(id = document.id) ?: Article()
}

Result.success(articles)
} catch (e: Exception) {
Result.failure(e)
}

override suspend fun getPlace(id: String): Result =
try {
val docSnapshot = fireStore.collection(PLACES_COLLECTION)
.document(id)
.get()
.await()

if (docSnapshot.exists()) {
Result.success(
docSnapshot.toObject()?.copy(id = docSnapshot.id) ?: Place()
)
} else {
Result.failure(NoSuchElementException("No place found with id $id"))
}
} catch (e: Exception) {
Result.failure(e)
}

override suspend fun getArticle(id: String): Result  =
try {
val docSnapshot = fireStore.collection(ARTICLES_COLLECTION)
.document(id)
.get()
.await()

if (docSnapshot.exists()) {
Result.success(
docSnapshot.toObject()?.copy(id = docSnapshot.id) ?: Article()
)
} else {
Result.failure(NoSuchElementException("No article found with id $id"))
}
} catch (e: Exception) {
Result.failure(e)
}

companion object {
const val ARTICLES_COLLECTION = "articles"
const val PLACES_COLLECTION = "places"
}
}
Модуль Firestore:

Код: Выделить всё

package com.amel.faerntourism.di

import com.amel.faerntourism.data.FireStoreRepository
import com.amel.faerntourism.data.FireStoreRepositoryImpl
import com.google.firebase.Firebase
import com.google.firebase.firestore.FirebaseFirestore
import com.google.firebase.firestore.firestore
import dagger.Module
import dagger.Provides
import dagger.hilt.InstallIn
import dagger.hilt.components.SingletonComponent
import javax.inject.Singleton

@Module
@InstallIn(SingletonComponent::class)
object FireStoreModule {

@Singleton
@Provides
fun provideFireStore(): FirebaseFirestore = Firebase.firestore

@Singleton
@Provides
fun providesFireStoreRepository(impl: FireStoreRepositoryImpl): FireStoreRepository = impl
}
< /code>
Основное действие: < /p>
package com.amel.faerntourism

import DailyInterestingPlaceNotificationWorker
import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.activity.viewModels
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.material3.Surface
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.navigation.NavHostController
import androidx.navigation.compose.NavHost
import androidx.navigation.compose.composable
import androidx.navigation.compose.rememberNavController
import androidx.work.ExistingPeriodicWorkPolicy
import androidx.work.OneTimeWorkRequestBuilder
import androidx.work.PeriodicWorkRequestBuilder
import androidx.work.WorkManager
import com.amel.faerntourism.ui.AuthViewModel
import com.amel.faerntourism.ui.screens.detailed.ArticleScreen
import com.amel.faerntourism.ui.screens.detailed.PlaceScreen
import com.amel.faerntourism.ui.screens.general.AccountScreen
import com.amel.faerntourism.ui.screens.general.ArticlesScreen
import com.amel.faerntourism.ui.screens.general.HomeScreen
import com.amel.faerntourism.ui.screens.general.ToursScreen
import com.amel.faerntourism.ui.theme.FaernTourismTheme
import dagger.hilt.android.AndroidEntryPoint
import java.util.concurrent.TimeUnit

@AndroidEntryPoint
class FaernActivity : ComponentActivity() {

private val authViewModel by viewModels()

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)

val periodicRequest = PeriodicWorkRequestBuilder(
12, TimeUnit.HOURS,
).build()

WorkManager.getInstance(applicationContext).enqueueUniquePeriodicWork(
DAILY_WORK_NAME,
ExistingPeriodicWorkPolicy.KEEP,
periodicRequest
)

setContent {
FaernTourismTheme {
Surface(
modifier = Modifier.fillMaxSize()
) {
val navController = rememberNavController()

FaernNavHost(navController, authViewModel)
}
}
}
}
}
Применение:

Код: Выделить всё

package com.amel.faerntourism

import android.app.Application
import dagger.hilt.android.HiltAndroidApp

@HiltAndroidApp
class FaernApplication : Application()
< /code>
androidmanifest: < /pbr /> 


























< /code>
Некоторые зависимости от рукояти: < /p>
implementation(libs.hilt.android)
kapt(libs.hilt.android.compiler)
implementation(libs.androidx.hilt.work)
kapt(libs.androidx.hilt.compiler)
implementation(libs.androidx.hilt.navigation.compose)

...

[versions]
hiltAndroid = "2.51.1"
hiltNavigationCompose = "1.2.0"
androidxHiltWork = "1.2.0"
androidxHiltCompiler = "1.2.0"

...

[libraries]
hilt-android = { group = "com.google.dagger", name = "hilt-android", version.ref = "hiltAndroid" }
hilt-android-compiler = { group = "com.google.dagger", name = "hilt-android-compiler", version.ref = "hiltAndroid" }
androidx-hilt-navigation-compose = { module = "androidx.hilt:hilt-navigation-compose", version.ref = "hiltNavigationCompose" }
androidx-hilt-work = { group = "androidx.hilt", name = "hilt-work", version.ref = "androidxHiltWork" }
androidx-hilt-compiler = { group = "androidx.hilt", name = "hilt-compiler", version.ref = "androidxHiltCompiler" }

Я пытался передать HiltWorkerFactory вручную следующим образом:
@HiltAndroidApp
class FaernApplication : Application(), Configuration.Provider {

@Inject
lateinit var workerFactory: HiltWorkerFactory

override val workManagerConfiguration: Configuration
get() = Configuration.Builder()
.setWorkerFactory(workerFactory)
.build()
}
< /code>
Но это тоже не помогло. < /p>
p.s. Уведомления включены на эмулятор.>

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

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

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

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

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

  • Похожие темы
    Ответы
    Просмотры
    Последнее сообщение
  • @AssistedInject с @HiltWorker не работает после обновления Gradle
    Anonymous » » в форуме Android
    0 Ответы
    11 Просмотры
    Последнее сообщение Anonymous
  • NoSuchMethodException, создаваемое HiltWorker с дополнительными параметрами
    Anonymous » » в форуме Android
    0 Ответы
    9 Просмотры
    Последнее сообщение Anonymous
  • Репозиторий Общий репозиторий с единицей работы для ядра C# .net с MongoDB
    Anonymous » » в форуме C#
    0 Ответы
    95 Просмотры
    Последнее сообщение Anonymous
  • Внедрить репозиторий в ядро ​​BackgroundService asp.net
    Anonymous » » в форуме C#
    0 Ответы
    33 Просмотры
    Последнее сообщение Anonymous
  • Как внедрить вариант использования в репозиторий с помощью платформы Koin DI
    Anonymous » » в форуме Android
    0 Ответы
    7 Просмотры
    Последнее сообщение Anonymous

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