adam
adam

Reputation: 231

Hilt and WorkManager error : java.lang.NoSuchMethodException:<init> [class android.content.Context, class androidx.work.WorkerParameters]

I am using work manager with Hilt but getting below error.

I am referring Android tutorial https://developer.android.com/training/dependency-injection/hilt-jetpack

Error

java.lang.NoSuchMethodException: com.debug.check.TestWorker.<init> [class android.content.Context, class androidx.work.WorkerParameters]
        at java.lang.Class.getConstructor0(Class.java:2332)
        at java.lang.Class.getDeclaredConstructor(Class.java:2170)
        at androidx.work.WorkerFactory.createWorkerWithDefaultFallback(WorkerFactory.java:95)
        at androidx.work.impl.WorkerWrapper.runWorker(WorkerWrapper.java:245)
        at androidx.work.impl.WorkerWrapper.run(WorkerWrapper.java:137)
        at androidx.work.impl.utils.SerialExecutor$Task.run(SerialExecutor.java:91)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
        at java.lang.Thread.run(Thread.java:929)

gradle version :

implementation 'androidx.work:work-runtime-ktx:2.7.1'
    // When using Kotlin.
kapt("androidx.hilt:hilt-compiler:1.0.0")
implementation 'androidx.hilt:hilt-work:1.0.0'

TestWorker

@HiltWorker
class TestWorker @AssistedInject constructor(
    @Assisted context: Context,
    @Assisted chatParameters: WorkerParameters,
    private val mainRepository: MainRepository
) : CoroutineWorker(context, chatParameters) {


    companion object {
        const val KEY_RESULT = "KEYRESULT"
    }


    override suspend fun doWork(): Result = coroutineScope {
        try {
            println("test")
            mainRepository.refreshMovies()
        } catch (e: Exception) {
            Result.failure()
        }
        Result.success()
    }
}  

MyApplication

@HiltAndroidApp
class MyApplication : Application(), Configuration.Provider {
    @Inject
    lateinit var workerFactory: HiltWorkerFactory

    override fun getWorkManagerConfiguration() =
        Configuration.Builder()
            .setWorkerFactory(workerFactory)
            .build()
    override fun onCreate() {
        super.onCreate()
       
    }
}

MainActivity

 @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main3);

        WorkManager workManager = WorkManager.getInstance(this);
        PeriodicWorkRequest periodicWorkRequest = new PeriodicWorkRequest.Builder(TestChatWorker.class
                , 5, TimeUnit.SECONDS)
                .addTag("test")
                .build();

        workManager.enqueueUniquePeriodicWork("test", ExistingPeriodicWorkPolicy.KEEP, periodicWorkRequest);
        workManager.getWorkInfoByIdLiveData(periodicWorkRequest.getId()).observe(this, new Observer<WorkInfo>() {
            @Override
            public void onChanged(WorkInfo workInfo) {
                if (workInfo != null) {
                    if (workInfo.getState() == WorkInfo.State.SUCCEEDED) {
                        String chatResult = workInfo.getOutputData().getString(TestWorker.KEY_RESULT);

                    }
                }
            }
        });
    }
}

It continues to fail in the initiate part. I tried to downgrade work manager to 2.6 but still not able to solve this issue.I already implemented in manifest.xml.

 <provider
            android:name="androidx.startup.InitializationProvider"
            android:authorities="${applicationId}.androidx-startup"
            android:exported="false"
            tools:node="merge">
            <!-- If you are using androidx.startup to initialize other components -->
            <meta-data
                android:name="androidx.work.impl.WorkManagerInitializer"
                android:value="androidx.startup"
                tools:node="remove" />
        </provider>

Upvotes: 21

Views: 9530

Answers (9)

Joonsoo
Joonsoo

Reputation: 918

If you have dependency on androidx.work:work-runtime-ktx:2.9.0 or higher:

AndroidManifest.xml:

<application>
    <provider
        android:name="androidx.startup.InitializationProvider"
        android:authorities="${applicationId}.androidx-startup"
        tools:node="remove" />
</application>

build.gradle (Module :app):

kapt "com.google.dagger:hilt-android-compiler:2.43.2"
kapt "androidx.hilt:hilt-compiler:1.2.0"

MainApplication.kt:

@HiltAndroidApp
class MainApplication : Application(), Configuration.Provider {
    @Inject
    lateinit var workerFactory: HiltWorkerFactory

    override val workManagerConfiguration: Configuration
        get() = Configuration.Builder()
            .setWorkerFactory(workerFactory)
            .build()
}

Upvotes: 1

Qadir Khan
Qadir Khan

Reputation: 305

You can try to solve this issue by the following ways.

Solution 1:

replace this kapt:

kapt 'androidx.hilt:hilt-compiler:1.0.0'    

with this version:

kapt "com.google.dagger:hilt-android-compiler:2.42"

Make sure you added all the dependencies for your module level build.gradle

 plugins {
    id 'com.android.application'
    id 'kotlin-android'
    id 'kotlin-kapt'
    id 'dagger.hilt.android.plugin'
    }



 dependencies {
   implementation 'androidx.hilt:hilt-work:1.0.0'
   implementation "com.google.dagger:hilt-android:2.42"

    kapt "com.google.dagger:hilt-android-compiler:2.42"
    kapt "com.google.dagger:hilt-compiler:2.42"
    }

Here is the build.gradle(Project level)

 dependencies {
    classpath "com.android.tools.build:gradle:7.2.2"
    classpath "org.jetbrains.kotlin:kotlin-gradle- 
    plugin:1.7.10"

    }
    }



plugins {
   id "com.google.dagger.hilt.android" version "2.42" apply 
   false
   }

   task clean(type: Delete) {
   delete rootProject.buildDir
   }

Solution 2:

check your Application class for workerFactory if you are passing other parameters to WorkManager class, Here is mine.

  @HiltAndroidApp
    class MyApplication: Application(), 
Configuration.Provider {
        @Inject
        lateinit var workerFactory: CustomWorkerFactory
    
        override fun getWorkManagerConfiguration() =
               Configuration.Builder()
                .setMinimumLoggingLevel(Log.DEBUG)
                .setWorkerFactory(workerFactory)
                .build()
        }



  class CustomWorkerFactory @Inject constructor(private val 
  api : ApiEndPoint): WorkerFactory(){
        override fun createWorker(
            appContext: Context,
            workerClassName: String,
            workerParameters: WorkerParameters
        ): ListenableWorker? = CustomWorker(api, context= 
  appContext, workerParameters)
    
    }

Solution 3: Make sure you added the provide tags in the manifest.xml file

   <provider
   android:name="androidx.startup.InitializationProvider"
   android:authorities="${applicationId}.androidx-startup"
   android:multiprocess="true"
   tools:node="remove">
   </provider>

Upvotes: 0

AI Shakil
AI Shakil

Reputation: 1762

If you are using ksp, then don't forget to use them both.

ksp("androidx.hilt:hilt-compiler:1.1.0")
ksp("com.google.dagger:hilt-compiler:2.48.1")

Upvotes: 12

KursikS
KursikS

Reputation: 326

Make sure you do not call WorkManager.initialize yourself

@Provides
@Singleton
override fun create(@ApplicationContext context: Context): WorkManager {
    // val configuration = Configuration.Builder().build()
    // WorkManager.initialize(context, configuration)
    return WorkManager.getInstance(context)
}

Upvotes: 2

Mohamed Medhat
Mohamed Medhat

Reputation: 1091

For me, I was using hilt.
I was missing @HiltWorker annotation on my worker class.

Upvotes: 0

bene25
bene25

Reputation: 588

I know example already has this piece of code, anyway in my case adding this code resolved the issue

override fun getWorkManagerConfiguration() =
      Configuration.Builder()
            .setWorkerFactory(workerFactory)
            .build()

Upvotes: 0

Hemant Kumar
Hemant Kumar

Reputation: 31

I was also facing this error and I had done everything you mentioned. In my case, the code for removing androidx.work.impl.WorkManagerInitializer was in the app module's AndroidManifest.xml. On moving that code to feature-specific AndroidManifest.xml I was able to fix the issue.

Upvotes: 0

Tausif
Tausif

Reputation: 896

In my project, I have used multiple worker class for different tasks. I also encountered the same issue and fixed this by adding android:multiprocess="true" in the manifest file "provider" tag. Sample code is given here :

<provider
            android:name="androidx.startup.InitializationProvider"
            android:authorities="${applicationId}.androidx-startup"
            android:multiprocess="true"
            tools:node="remove">
</provider>

Upvotes: 5

Chepech
Chepech

Reputation: 5581

Two things you should check:

Check that you are using the correct provider entry depending on the version that you are using the AndroidManifest, this one worked for me:

<provider
    android:name="androidx.startup.InitializationProvider"
    android:authorities="${applicationId}.androidx-startup"
    tools:node="remove">
</provider>

Check that you have this two kapt dependencies on your build.gradle (this is not mentioned on the doc, and this was the cause for me having the same issue):

kapt "com.google.dagger:hilt-android-compiler:2.42"
kapt "androidx.hilt:hilt-compiler:1.0.0"

Upvotes: 42

Related Questions