Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/kotlin/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android HiltWorkerFactory:在应用程序启动时配置WorkManagerInitializer_Android_Kotlin_Dependency Injection_Android Workmanager_Dagger Hilt - Fatal编程技术网

Android HiltWorkerFactory:在应用程序启动时配置WorkManagerInitializer

Android HiltWorkerFactory:在应用程序启动时配置WorkManagerInitializer,android,kotlin,dependency-injection,android-workmanager,dagger-hilt,Android,Kotlin,Dependency Injection,Android Workmanager,Dagger Hilt,WorkManagerInitializer需要配置setWorkerFactory,以便将依赖项注入到Worker类。介绍了AppStartup中的workManager初始化,但未提供有关如何配置setWorkerFactory的任何详细信息。如果有人能提出任何解决方案或解决办法,那将非常有帮助。 问题是我无法将自己的依赖项注入workerClass。我已经在下面介绍了两个场景来解释这个案例:` 工作场景#1: //这个电话很好用 class-AppWorker@WorkerInject构造

WorkManagerInitializer
需要配置setWorkerFactory,以便将依赖项注入到
Worker
类。介绍了AppStartup中的workManager初始化,但未提供有关如何配置setWorkerFactory的任何详细信息。如果有人能提出任何解决方案或解决办法,那将非常有帮助。 问题是我无法将自己的依赖项注入workerClass。我已经在下面介绍了两个场景来解释这个案例:` 工作场景#1:

//这个电话很好用

class-AppWorker@WorkerInject构造函数(
@辅助语境:语境,
@辅助工作参数:工作参数
):Worker(上下文、workerParams){
伴星{
val workType=“workType”
}
重写fun doWork():结果{
返回Result.success()
}
}
失败的场景#2:

//初始化WorkManager。
类WorkManagerInitializer:初始值设定项{
覆盖乐趣创建(上下文:上下文):WorkManager{
//如何获取配置所需的workFactory。
var workerFactory:HiltWorkerFactory?=null
val configuration=configuration.Builder()
.setWorkerFactory(workerFactory)
.build()
WorkManager.initialize(上下文、配置)
返回WorkManager.getInstance(上下文)
}
覆盖乐趣依赖项():列表{
//不依赖于其他库。
返回空列表()
}
}
@希尔顿酒店
类BaseApp:Application(),Configuration.Provider{
@注入lateinit var workerFactory:HiltWorkerFactory
重写getWorkManagerConfiguration()=
Configuration.Builder()
.setWorkerFactory(workerFactory)
.build()
初始化{
setDefaultUncaughtExceptionHandler(ThreadExceptionHandler())
}
重写fun onCreate(){
super.onCreate()
if(BuildConfig.DEBUG){
木材.植物(DebugTree())
}
}
}
Manifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    package="com.example.baseapp">

      <application
        android:name="com.example.baseapp.startup.BaseApp"
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/Theme.MyApp"
        >
        <activity android:name="com.example.baseapp.gui.activities.MainActivity"
            android:screenOrientation="portrait">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

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

            <meta-data                android:name="com.example.baseapp.startup.AppServicesInitializer"
                android:value="androidx.startup" />

        </provider>
        <provider
            android:name="androidx.work.impl.WorkManagerInitializer"
            android:authorities="${applicationId}.workmanager-init"
            tools:node="remove"/>

    </application>

</manifest>

//应用程序符合并成功运行,但未能调用doWork()

AppWorker类dowork()方法未使用AppStartup中定义的WorkManagerInitializer调用。以下是logcat中的错误:

2020-09-24 19:38:41.811 23803-23863/com.example.baseapp E/WM WorkerFactory:无法实例化com.example.baselib.services.local.work\u manager.worker.AppWorker java.lang.NoSuchMethodException:com.example.baselib.services.local.work\u manager.worker.AppWorker。[类android.content.Context,类androidx.work.WorkerParameters] 位于java.lang.Class.getConstructor0(Class.java:2332) 位于java.lang.Class.getDeclaredConstructor(Class.java:2170) 位于androidx.work.WorkerFactory.createWorkerWithDefaultFallback(WorkerFactory.java:95) 位于androidx.work.impl.workerRapper.runWorker(workerRapper.java:242) 在androidx.work.impl.workerRapper.run(workerRapper.java:136) 位于androidx.work.impl.utils.SerialExecutor$Task.run(SerialExecutor.java:91) 位于java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167) 位于java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
在java.lang.Thread.run(Thread.java:923)

中,您可以简单地使用
@WorkerInject
注释注入依赖项,如下所示,然后摆脱工厂:

class ExampleWorker@WorkerInject构造函数(
@上下文:上下文,
@辅助工人参数:工人参数,
依赖关系:你的类依赖关系
):Worker(appContext,workerParams){…}
然后,让您的
应用程序
类实现
配置.Provider
接口,注入
HiltWorkFactory
的实例,并将其传递到
WorkManager
配置中,如下所示:

@HiltAndroidApp
类ExampleApplication:Application(),Configuration.Provider{
@注入lateinit var workerFactory:HiltWorkerFactory
重写getWorkManagerConfiguration()=
Configuration.Builder()
.setWorkerFactory(workerFactory)
.build()
}
请注意,还必须从
AndroidManifest.xml
中删除默认初始值设定项:


适用于将刀柄与
androidx.work-*
版本
2.6.0-alpha01
或更高版本一起使用的人:

从开始,此版本开始在内部使用新的
androidx.startup
jetpack库。 因此,从
AndroidManifest.xml
中删除
WorkManager
的默认初始值设定项的方法有所改变

如果您在应用程序的其他位置使用了
androidx.startup
,请替换为:


否则,您可以通过将旧更改替换为以下内容来完全禁用
androidx.startup



这样,您的
HiltWorker
将再次使用子类应用程序中的工厂。不幸的是,您将失去延迟启动的(明显)好处。

我们可以直接从
初始值设定项使用HiltWorkerFactory。
下面是一个例子:

class CustomWorkManagerInitializer : Initializer<WorkManager> {

    override fun create(context: Context): WorkManager {
        val workerFactory = getWorkerFactory(appContext = context.applicationContext)
        val config = Configuration.Builder()
            .setWorkerFactory(workerFactory)
            .build()
        WorkManager.initialize(context, config)
        return WorkManager.getInstance(context)
    }

    override fun dependencies(): MutableList<Class<out Initializer<*>>> = mutableListOf()

    private fun getWorkerFactory(appContext: Context): HiltWorkerFactory {
        val workManagerEntryPoint = EntryPointAccessors.fromApplication(
            appContext,
            WorkManagerInitializerEntryPoint::class.java
        )
        return workManagerEntryPoint.hiltWorkerFactory()
    }

    @InstallIn(SingletonComponent::class)
    @EntryPoint
    interface WorkManagerInitializerEntryPoint {
        fun hiltWorkerFactory(): HiltWorkerFactory
    }
}
还禁用默认的
WorkManager
初始值设定项,并在清单中添加自定义项

<provider
        android:name="androidx.startup.InitializationProvider"
        android:authorities="${applicationId}.androidx-startup"
        android:exported="false"
        tools:node="merge">
        <!-- disable default -->
        <meta-data
            android:name="androidx.work.WorkManagerInitializer"
            android:value="@string/androidx_startup"
            tools:node="remove" />
        <!-- enable custom -->
        <meta-data
            android:name="com.acme.app.initializer.CustomWorkManagerInitializer"
            android:value="androidx.startup" />
</provider>


我已经实现了您建议的解决方案,将依赖项注入WorkerClass。但似乎不可能在WorkManagerInitializer中设置场景中描述的“HiltWorkerFactory”#2@Chandra能否共享manifest.xml以及应用程序类?除“Work Manager”之外的所有hilt依赖项都在AppStartup时初始化。我对WorkManagerInitializer类代码进行了注释,以便可以在应用程序类中设置“HiltWorkerFactory”。您的应用程序似乎仍在使用场景2中所述的WorkManagerInitializer类。你能和我分享一下吗
<provider
        android:name="androidx.startup.InitializationProvider"
        android:authorities="${applicationId}.androidx-startup"
        android:exported="false"
        tools:node="merge">
        <!-- disable default -->
        <meta-data
            android:name="androidx.work.WorkManagerInitializer"
            android:value="@string/androidx_startup"
            tools:node="remove" />
        <!-- enable custom -->
        <meta-data
            android:name="com.acme.app.initializer.CustomWorkManagerInitializer"
            android:value="androidx.startup" />
</provider>