【发布时间】:2019-05-09 07:44:37
【问题描述】:
我在我的项目中从Android Priority JobQueue library 迁移到AndroidX WorkManager,但它的构建方式是Worker 应该是这样的:
TaskSchedulerWorker.kt
class TaskSchedulerWorker(
private val workManager: WorkManager = WorkManager.getInstance()
) : TaskScheduler {
override fun execute(useCaseWrapper: UseCaseWrapper) {
workManager.beginUniqueWork(
useCaseWrapper.useCaseName,
ExistingWorkPolicy.APPEND,
OneTimeWorkRequest.from(UseCaseWrapperWorker::class.java)
).enqueue()
}
override fun onCancel(useCaseWrapper: UseCaseWrapper) {
workManager.cancelUniqueWork(useCaseWrapper.useCaseName)
}
}
UseCaseWrapperWorker.kt
class UseCaseWrapperWorker(
context: Context,
params: WorkerParams,
private val useCaseWrapper: UseCaseWrapper
) : Worker(context, params) {
override fun doWork(): Result {
return try {
useCaseWrapper.execute()
Result.success()
} catch (ex: Exception) {
ex.printStackTrace()
Result.failure()
}
}
}
关键是,如果我尝试使用这些类运行我的应用程序,我会收到下一个错误:
2019-05-09 09:34:45.784 27260-27443/com.mobileapp.debug E/WM-WorkerFactory: Could not instantiate com.mobileapp.domain.jobqueue.UseCaseWrapperWorker
java.lang.NoSuchMethodException: com.mobileapp.domain.jobqueue.UseCaseWrapperWorker.<init> [class android.content.Context, class androidx.work.WorkerParameters]
at java.lang.Class.getConstructor0(Class.java:2328)
at java.lang.Class.getDeclaredConstructor(Class.java:2167)
at androidx.work.WorkerFactory.createWorkerWithDefaultFallback(WorkerFactory.java:92)
at androidx.work.impl.WorkerWrapper.runWorker(WorkerWrapper.java:234)
at androidx.work.impl.WorkerWrapper.run(WorkerWrapper.java:128)
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:764)
2019-05-09 09:34:45.784 27260-27443/com.mobileapp.debug E/WM-WorkerWrapper: Could not create Worker com.mobileapp.domain.jobqueue.UseCaseWrapperWorker
因为Worker 构造函数不能有超过两个默认参数(Context 和WorkerParameters)。
我无法弄清楚如何使用接收Context、WorkerParameters 和UseCaseWrapper 的构造函数来实现UseCaseWrapperWorker 类,并使用@987654336 从TaskSchedulerWorker 调用它@指令。
已编辑:
我尝试实现CustomWorkerFactory 和CustomWorker 以将UseCaseWrapper 传递给它们。问题是我必须在Application#onCreate 方法(Android Developer Documentation)中初始化WorkManager,而此时我无法访问所需的UseCaseWrapper。
TaskSchedulerWorker.kt
(WorkManager init 应该在 Application#onCreate)
class TaskSchedulerWorker(private val appContext: Context) : TaskScheduler {
override fun execute(useCaseWrapper: UseCaseWrapper) {
val workerFactory = CustomWorkerFactory(useCaseWrapper)
val configuration = Configuration.Builder()
.setWorkerFactory(workerFactory)
.build()
WorkManager.initialize(context, configuration)
WorkManager.getInstance().beginWork(
"uniqueWorkName",
ExistingWorkPolicy.APPEND,
OneTimeWorkRequest.from(CustomWorker::class.java)
)
}
}
CustomWorkerFactory.kt
class CustomWorkerFactory(private val useCaseWrapper: UseCaseWrapper) : WorkerFactory() {
override fun createWorker(
appContext: Context,
workerClassName: String,
workerParameters: WorkerParameters
): ListenableWorker? {
return CustomWorker(appContext, workerParameters, useCaseWrapper)
}
}
CustomWorker.kt
class CustomWorker(
context: Context,
params: WorkerParameters
) : Worker(context, params) {
private var useCaseWrapper: UseCaseWrapper? = null
constructor(
context: Context,
params: WorkerParameters,
useCaseWrapper: UseCaseWrapper
) : this(context, params) {
this.useCaseWrapper = useCaseWrapper
}
override fun doWork(): Result {
return useCaseWrapper?.let { useCaseWrapper ->
try {
useCaseWrapper.execute()
Result.success()
} catch (ex: Exception) {
Result.failure()
}
} ?: Result.failure()
}
}
RuntimeException 抛出的是:
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.mobileapp.debug/com.mobileapp.home.view.activity.HomeActivity}: java.lang.IllegalStateException: WorkManager is already initialized.
Did you try to initialize it manually without disabling WorkManagerInitializer? See WorkManager#initialize(Context, Configuration) or the class levelJavadoc for more information.
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3086)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3229)
at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:78)
at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:108)
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:68)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1926)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loop(Looper.java:214)
at android.app.ActivityThread.main(ActivityThread.java:6981)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1445)
Caused by: java.lang.IllegalStateException: WorkManager is already initialized. Did you try to initialize it manually without disabling WorkManagerInitializer?
See WorkManager#initialize(Context, Configuration) or the class levelJavadoc for more information.
at androidx.work.impl.WorkManagerImpl.initialize(WorkManagerImpl.java:137)
at androidx.work.WorkManager.initialize(WorkManager.java:169)
at com.mobileapp.domain.worker.TaskSchedulerWorker.execute(TaskSchedulerWorker.kt:20)
at com.mobileapp.domain.usecase.UseCaseHandler.execute(UseCaseHandler.kt:41)
at com.mobileapp.domain.usecase.UseCaseCall.execute(UseCaseCall.kt:50)
at com.mobileapp.home.view.presenter.HomePresenter.getConfigurationJSON(HomePresenter.kt:107)
at com.mobileapp.home.view.activity.HomeActivity.initComponents(HomeActivity.kt:107)
at com.mobileapp.home.view.activity.HomeActivity.onCreate(HomeActivity.kt:67)
at android.app.Activity.performCreate(Activity.java:7326)
at android.app.Activity.performCreate(Activity.java:7317)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1271)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3066)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3229)
at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:78)
at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:108)
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:68)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1926)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loop(Looper.java:214)
at android.app.ActivityThread.main(ActivityThread.java:6981)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1445)
有什么建议吗?
【问题讨论】:
-
对于工人实施中的客户参数,我面临同样的问题
java.lang.NoSuchMethodException:。你能解决这个问题吗? -
我试图解决同样的问题,并以您的代码为例。仅从清单文件中禁用了默认初始化程序,并且它定期运行。
标签: android kotlin androidx android-workmanager