我已经按照Android Developer's教程使用工人管理器结构在后台运行我的代码,但是无论何时我尝试使它的工人无法入队,都会出现以下错误:
2018-10-04 22:25:47.004 28669-28885/app.package.com.debug E/DefaultWorkerFactory: Could not instantiate app.package.com.MyWorker
java.lang.NoSuchMethodException: <init> []
at java.lang.Class.getConstructor0(Class.java:2320)
at java.lang.Class.getDeclaredConstructor(Class.java:2166)
at androidx.work.DefaultWorkerFactory.createWorker(DefaultWorkerFactory.java:58)
at androidx.work.impl.WorkerWrapper.runWorker(WorkerWrapper.java:180)
at androidx.work.impl.WorkerWrapper.run(WorkerWrapper.java:117)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1162)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:636)
at java.lang.Thread.run(Thread.java:764)
2018-10-04 22:25:47.005 28669-28885/app.package.com.debug E/WorkerWrapper: Could for create Worker app.package.com.MyWorker
我已经看到这个问题可能与工作程序上的默认构造函数有关,但是我已经使用了正确的函数而不是不推荐使用的默认函数。
我的工人被宣布为:
public class MyWorker extends Worker {
public MyWorker(@NonNull Context context, @NonNull WorkerParameters workerParams) {
super(context, workerParams);
}
@NonNull
@Override
public Result doWork() {
// Doesn't even get called
}
}
它像这样排队:
WorkManager workManager = WorkManager.getInstance();
if (myWorkerRequest == null) {
myWorkerRequest = new OneTimeWorkRequest.Builder(MyWorker.class)
.setConstraints(new Constraints.Builder()
.setRequiredNetworkType(NetworkType.CONNECTED)
.build())
.build();
}
WorkStatus workStatus = workManager.getStatusById(myWorkerRequest.getId()).getValue();
if (workStatus == null || !workStatus.getState().isFinished()) {
workManager.enqueue(myWorkerRequest);
}
我没有看到与示例不同的内容,因此我想了解还有什么可能影响我的代码导致此崩溃。可能与ProGuard有关吗?
我的版本是1.0.0-alpha09
谢谢!
答案 0 :(得分:15)
这是带有WorkManager 1.0.0-alpha09的known issue,已被标记为已固定为alpha10。
作为一种解决方法,您可以在proguard配置中添加以下几行:
-keepclassmembers class * extends androidx.work.Worker {
public <init>(android.content.Context,androidx.work.WorkerParameters);
}
答案 1 :(得分:4)
如果您使用按需初始化并且Dagger注入了整个配置,请确保按照pull request的建议通过在AndroidManifest中添加以下提供程序来删除WorkManager的默认初始化。这是唯一帮助我的事情。有关更多详细信息,请检查blog。
<!-- Remove WorkManager default initialization -->
<provider
android:name="androidx.work.impl.WorkManagerInitializer"
android:authorities="${applicationId}.workmanager-init"
tools:node="remove" />
答案 2 :(得分:3)
我有同样的问题。对我来说,问题的原因是我的Worker类是一个嵌套类。当我将它设为一堂独立课时,它就起作用了。
答案 3 :(得分:3)
如果您使用 Kotlin,要记住的另一件事是 Worker 类可以嵌套,但它不能标记为 inner
。
我怀疑如果您使用 Java,如果您将其标记为 static
,您也可以使用嵌套类。但我还没有测试过。
答案 4 :(得分:2)
我在稳定版本1.0.0中有此问题,并通过将我的工作者类公开来解决此问题。
select author_id1, shelf_id1, max(num_pages1)
(
select
Author1.author_id author_id1, Author1.shelf_id shelf_id1, Author1.number_pages_witten num_pages1,
Author2.author_id author_id2, Author2.shelf_id shelf_id2, Author2.number_pages_witten num_pages2
from Author Author1 left join Author Author2
on Author1.author_id = Author2.author_id and Author1.shelf_id = Author2.shelf_id
and Author1.number_pages_witten != Author2.number_pages_witten
)ds
group by author_id1, shelf_id1
答案 5 :(得分:0)
对我来说,问题是我的kotlin类的构造函数:
错误
class MyWorker(val app: Application, workerParams: WorkerParameters): Worker(app, workerParams)
好
class MyWorker(val context: Context, workerParams: WorkerParameters): Worker(context, workerParams)
答案 6 :(得分:0)
如果您将Worker
与Hilt
一起使用,则除了所有other requirements之外,还要确保您also adding HiltWorkerFactory
进入您的Application
班
@HiltAndroidApp
class App: Application(), Configuration.Provider {
@Inject
lateinit var workerFactory: HiltWorkerFactory
override fun getWorkManagerConfiguration() =
Configuration.Builder()
.setWorkerFactory(workerFactory)
.build()
}