Android Work Manager:“无法实例化Worker”

时间:2018-10-05 01:40:09

标签: android androidx android-workmanager

我已经按照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

谢谢!

7 个答案:

答案 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)

除了Tony's answer

如果您使用 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)

如果您将WorkerHilt一起使用,则除了所有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()
}