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>