Android工作管理器:"无法实例化工作者"

ica*_*ual 12 android android-workmanager androidx

我已经按照Android开发人员的教程使用工作管理器结构在后台运行我的代码,但是当我尝试将我的工作人员排队时它不会运行,我收到以下错误:

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
Run Code Online (Sandbox Code Playgroud)

我已经看到这个问题可能与worker上的默认构造函数有关但我已经使用了正确的构造函数而不是不推荐使用的默认函数.

我的工人被宣布为:

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
    }
}
Run Code Online (Sandbox Code Playgroud)

它就像这样排队:

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);
}
Run Code Online (Sandbox Code Playgroud)

我没有看到与示例有什么不同,所以我想了解还有什么可能会影响我的代码导致此崩溃.它可能与ProGuard有关吗?

我的版本是 1.0.0-alpha09

谢谢!

ian*_*ake 16

这是WorkManager 1.0.0-alpha09 的已知问题,已针对alpha10标记为已修复.

作为解决方法,您可以将以下行添加到proguard配置中:

-keepclassmembers class * extends androidx.work.Worker {
    public <init>(android.content.Context,androidx.work.WorkerParameters);
}
Run Code Online (Sandbox Code Playgroud)

  • 我在1.0.0-beta01中也遇到过同样的问题,而且我的构造函数(自定义工作程序)似乎是程序包私有的。为了使经理工作,必须公开。我公开了构造函数,它就像一个魅力。 (5认同)
  • @ianhanniballake 所以......即使你不使用它,你也需要添加 proguard 限制? (2认同)
  • 2.2.0 中同样的异常 (2认同)

小智 8

我遇到了同样的问题,我的解决方案就在这里

  1. 我更新工作管理器版本“2.6.0-alpha02”,以前的版本是“2.5.0”
  2. 您需要将具有元数据的提供者添加到清单中。

    <provider
      android:name="androidx.startup.InitializationProvider"
      android:authorities="${applicationId}.androidx-startup"
      android:exported="false"
      tools:node="merge">
      <meta-data
        android:name="androidx.work.WorkManagerInitializer"
        android:value="androidx.startup"
        tools:node="remove" />
    </provider>
Run Code Online (Sandbox Code Playgroud)

  1. 您需要将 HiltWorkerFactory 注入到 Application 类并 setWorkerFactory

@HiltAndroidApp
class App: Application(), Configuration.Provider {

@Inject
lateinit var workerFactory: HiltWorkerFactory

override fun getWorkManagerConfiguration() =
    Configuration.Builder()
        .setWorkerFactory(workerFactory)
        .build()
}
Run Code Online (Sandbox Code Playgroud)


Ton*_*ony 7

我遇到过同样的问题。对我来说,问题的原因是我的Worker类是一个嵌套类。从我成为独立班级的那一刻起,它就起作用了。

  • 这也解决了我的问题。添加混淆器排除并没有。 (2认同)
  • 谢谢,拯救了我的一天!仅限独立班!但有什么区别呢? (2认同)

Mic*_*lsx 6

我在稳定的1.0.0版中遇到了这个问题,并通过将我的工人阶级公开化来解决此问题。

class MyWorker extends Worker {...} > public class MyWorker extends Worker {...}
Run Code Online (Sandbox Code Playgroud)


Luj*_*a93 6

如果您使用按需初始化和 Dagger 来注入整个配置,请确保通过在 AndroidManifest 中添加以下提供程序来删除 WorkManager 默认初始化,如pull request所建议的。这是唯一对我有帮助的事情。有关更多详细信息,请查看博客

<!-- Remove WorkManager default initialization -->
<provider
    android:name="androidx.work.impl.WorkManagerInitializer"
    android:authorities="${applicationId}.workmanager-init"
    tools:node="remove" />
Run Code Online (Sandbox Code Playgroud)

  • 很有帮助。更多解释可以从官方文档 https://developer.android.com/topic/libraries/architecture/workmanager/advanced/custom-configuration 找到 (3认同)

gar*_*ple 6

除了托尼的回答之外:

如果您使用 Kotlin,要记住的另一件事是 Worker 类可以嵌套,但不能将其标记为inner.

我怀疑如果您使用 Java,如果您将其标记为static. 但我没有测试过这个。


小智 5

我的问题是我的 kotlin 类的构造函数:

错误的

class MyWorker(val app: Application, workerParams: WorkerParameters): Worker(app, workerParams)
Run Code Online (Sandbox Code Playgroud)

好的

class MyWorker(val context: Context, workerParams: WorkerParameters): Worker(context, workerParams)
Run Code Online (Sandbox Code Playgroud)