E/WM-WorkerFactory: 无法实例化 com.isopod.gateauth.UnifyIDAPIHandler$ModelTrainer

E/WM-WorkerFactory: Could not instantiate com.isopod.gateauth.UnifyIDAPIHandler$ModelTrainer

所以我尝试使用标准 android 工作库安排任务,但我得到以下错误跟踪

E/WM-WorkerFactory: Could not instantiate com.isopod.gateauth.UnifyIDAPIHandler$ModelTrainer
    java.lang.NoSuchMethodException: <init> [class android.content.Context, class androidx.work.WorkerParameters]
        at java.lang.Class.getConstructor0(Class.java:2327)
        at java.lang.Class.getDeclaredConstructor(Class.java:2166)
        at androidx.work.WorkerFactory.createWorkerWithDefaultFallback(WorkerFactory.java:95)
        at androidx.work.impl.WorkerWrapper.runWorker(WorkerWrapper.java:242)
        at androidx.work.impl.WorkerWrapper.run(WorkerWrapper.java:136)
        at androidx.work.impl.utils.SerialExecutor$Task.run(SerialExecutor.java:91)
        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)
E/WM-WorkerWrapper: Could not create Worker com.isopod.gateauth.UnifyIDAPIHandler$ModelTrainer

我正在使用标准工作库。我看到其他用户在尝试注入自定义初始化程序时遇到了这个问题,但我相信我使用的是默认库,它应该能够自行正确初始化

这是我的应用程序级别的依赖项 build.gradle:

dependencies {
    implementation fileTree(dir: 'libs', include: ['*.jar'])

    implementation 'id.unify.sdk:sdk-gaitauth:1.3.8'

    implementation "androidx.work:work-runtime:2.4.0"

    implementation 'com.google.guava:listenablefuture:9999.0-empty-to-avoid-conflict-with-guava'


    implementation 'androidx.appcompat:appcompat:1.2.0'
    implementation 'androidx.constraintlayout:constraintlayout:2.0.1'
    testImplementation 'junit:junit:4.12'
    androidTestImplementation 'androidx.test.ext:junit:1.1.2'
    androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0'
}

这是我正在尝试使用的 class 的代码

public class ModelTrainer extends Worker {

    public ModelTrainer (Context context, WorkerParameters params){
        super(context, params);
    }

    @NonNull
    @Override
    public Result doWork() {
        try {
            if (curStatus == GaitAuthStatus.READY_TO_TRAIN) {
                gaitModel.train();
                curStatus = GaitAuthStatus.TRAINING;
            } else if (curStatus == GaitAuthStatus.TRAINING) {
                gaitModel.refresh();
            }

        } catch (GaitModelException e) {
            e.printStackTrace();
            return Result.failure();
        }

        if (gaitModel.getStatus() == GaitModel.Status.READY) {
            curStatus = GaitAuthStatus.READY;
        } else if (gaitModel.getStatus() == GaitModel.Status.FAILED) {
            return Result.failure();
        }

        return Result.success();
    }
}

这是我开始工作的代码

WorkRequest trainModelRequest = new OneTimeWorkRequest.Builder(ModelTrainer.class).build();

WorkManager.getInstance(mainActivity.getApplicationContext()).enqueue(trainModelRequest);
mainActivity.addTextToScreen("Model training started");

还值得注意的是,我收到了一堆看起来很奇怪的消息 android 工作室 运行 日志:

W/isopod.gateaut: Accessing hidden method Lcom/android/org/conscrypt/OpenSSLSocketImpl;->setAlpnProtocols([B)V (light greylist, reflection)
W/isopod.gateaut: Accessing hidden method Lcom/android/org/conscrypt/OpenSSLSocketImpl;->getAlpnSelectedProtocol()[B (light greylist, reflection)
I/org.libsodium.jni.NaCl: librarypath=/system/lib
W/pool-3-thread-1: type=1400 audit(0.0:32027): avc: denied { read } for uid=10158 name="cache" dev="dm-0" ino=31 scontext=u:r:untrusted_app:s0:c158,c256,c512,c768 tcontext=u:object_r:cache_file:s0 tclass=lnk_file permissive=0
W/pool-3-thread-1: type=1400 audit(0.0:32028): avc: denied { read } for uid=10158 name="cache" dev="dm-0" ino=31 scontext=u:r:untrusted_app:s0:c158,c256,c512,c768 tcontext=u:object_r:cache_file:s0 tclass=lnk_file permissive=0
I/RootBeer: LOOKING FOR BINARY: /data/local/su Absent :(
    LOOKING FOR BINARY: /data/local/bin/su Absent :(
    LOOKING FOR BINARY: /data/local/xbin/su Absent :(
    LOOKING FOR BINARY: /sbin/su Absent :(
    LOOKING FOR BINARY: /su/bin/su Absent :(
    LOOKING FOR BINARY: /system/bin/su Absent :(
    LOOKING FOR BINARY: /system/bin/.ext/su Absent :(
    LOOKING FOR BINARY: /system/bin/failsafe/su Absent :(
    LOOKING FOR BINARY: /system/sd/xbin/su Absent :(
    LOOKING FOR BINARY: /system/usr/we-need-root/su Absent :(
    LOOKING FOR BINARY: /system/xbin/su Absent :(
    LOOKING FOR BINARY: /cachesu Absent :(
    LOOKING FOR BINARY: /datasu Absent :(
    LOOKING FOR BINARY: /devsu Absent :(
W/System: A resource failed to call close. 
I/chatty: uid=10158(com.isopod.gateauth) FinalizerDaemon identical 1 line
W/System: A resource failed to call close. 
    A resource failed to call end. 
W/isopod.gateaut: Accessing hidden field Ljava/nio/Buffer;->address:J (light greylist, reflection)
W/isopod.gateaut: Accessing hidden field Lsun/misc/Unsafe;->theUnsafe:Lsun/misc/Unsafe; (light greylist, reflection)
D/ModelStore: Saved model d9d51fd3-2a9b-4af1-97f3-3d67424e8785 into storage, model data length 0 bytes

任何人都可以告诉我可能发生的事情吗?我很困惑。我几乎遵循了 android 文档中的设置指南和示例,所以如果我遇到这个问题,我相信很多其他人也会遇到这个问题

引用可爱的 u/Zhuinden 在 reddit 上的回答,

如果这是一个 worker,您需要有一个构造函数来获取 Context、WorkerParameters,并且没有其他参数。就这两个。

在您的情况下,问题是您的 class 是内部 class,但在 Java 中,这意味着它也有对其父级的引用。您需要将其定义为静态 class

确实,在 class 定义中添加 static 解决了这个问题,但由于我想通过它传递数据,所以我将其设为独立的 public class 并使用了 workmanager 数据class 传递参数