【问题标题】:Periodic Custom WorkManager not Triggering doWork()定期自定义 WorkManager 不触发 doWork()
【发布时间】:2023-02-24 00:47:39
【问题描述】:

我正在为一项周期性任务实施自定义 WorkManager(使用 AppStartup 和 Hilt),但经过大量修补、研究和等待后,任务并未启动。

下面是我的设置

工人阶级

覆盖 doWork() 返回 Result.success()Result.error()。我有一个 Companion 使用静态 schedule() 来设置约束条件,要求并打电话WorkManager.getInstance(context)

class ScoresWorker @AssistedInject constructor(
    @Assisted private val context: Context,
    @Assisted params: WorkerParameters,
    private val db: ScoresDatabase,
    private val api: ScoresAPI
) : CoroutineWorker(context, params) {

    private val dao = db.dao
    override suspend fun doWork(): Result {
        Timber.i("DoWork Called")
        return try {
            val response = api.getFixturesByDate()

            dao.clearFixtures()
            dao.insertFixtures(response.response.map { it.toEntity() })
            Result.success()
        
        } catch (e: Exception) {
            Timber.i("WorKError - Exception")
            Result.failure(workDataOf(SCORES_WORKER_ERROR_KEY to e.localizedMessage))
        }
    }

    companion object {

        private const val SCORES_WORKER_ID = "scores_worker"
        fun schedule(context: Context) {

            Timber.i("companion Obj schedule() called")
            val constraints = Constraints.Builder()
                .setRequiredNetworkType(NetworkType.CONNECTED)
                .build()

            val request = PeriodicWorkRequestBuilder<ScoresWorker>(
                15, TimeUnit.MINUTES, 5, TimeUnit.MINUTES
            ).setConstraints(constraints)
                .build()

            WorkManager.getInstance(context)
                .enqueueUniquePeriodicWork(
                    SCORES_WORKER_ID, ExistingPeriodicWorkPolicy.KEEP, request
                )
        }
    }
}

助手类

单例助手类调用上面的ScoresWorker.schedule(context) 并确保 WorkManager 只初始化一次并且只有一个实例。

@Singleton
class WorkManagerInitializer @Inject constructor(
    @ApplicationContext private val context: Context, ) {

    private var isInitialized: Boolean = false
    fun initializeWorkManager() {

        Timber.i("initialization called - value: $isInitialized")
        if (isInitialized) return
        isInitialized = true
        ScoresWorker.schedule(context)
    }
}

启动时

为了提高应用程序启动性能,我从应用程序启动序列中删除了诸如调度 WorkManager 之类的繁重内容,将其移至 onStart()。

@AndroidEntryPoint
class MainActivity : ComponentActivity() {

    @Inject
    lateinit var initializationHelper: WorkManagerInitializer
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent { .... }
    }

    override fun onStart() {
        super.onStart()
        initializationHelper.initializeWorkManager()
    }
}

应用类和

应用程序类实现Configuration.Provider界面

@HiltAndroidApp
class InstantScoreApp : Application(), Configuration.Provider {
    override fun onCreate() { ... }

    @Inject
    lateinit var workerFactory: HiltWorkerFactory

    override fun getWorkManagerConfiguration(): Configuration {
        return Configuration.Builder()
            .setWorkerFactory(workerFactory)
            .build()
    }
}

显现

首先按照 Docs 中的描述尝试这种方法

...
<provider
   android:name="androidx.startup.InitializationProvider"
   android:authorities="${applicationId}.androidx-startup"
   tools:node="remove"
         >

        </provider>-->
    </application>

这也没有用。

<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>

我在work-runtime-ktx v 2.8.0startup-runtime v1.1.

我需要帮助了解我可能缺少什么才能使此设置正常工作。请帮助。

【问题讨论】:

  • logcat 中是否显示任何错误并检查互联网是否可用?
  • 另请检查您是否在清单文件中添加了 InstantScoreApp 应用程序类。
  • 嗨 Tausif,到目前为止没有发现任何错误,并且已经在模拟器和物理设备上都进行了尝试。互联网已开启并已申请互联网许可。通过android:name=".InstantScoreApp" 标签将应用程序类添加到清单中。
  • 请检查以下库是否已添加到您的 gradle 文件中。实施“androidx.work:work-runtime-ktx:2.7.0”实施(“androidx.hilt:hilt-work:1.0.0”)kapt(“androidx.hilt:hilt-compiler:1.0.0”)kapt“ com.google.dagger:hilt-android-compiler:2.39.1"
  • 您似乎在 ScoresWorker 类中扩展了 CoroutineWorker。您可以尝试使用 worker 类而不是 CoroutineWorker。我还在答案部分提供了详细信息。

标签: android android-workmanager


【解决方案1】:

这是我的工作代码, 在清单文件中:

 android:name=".MainApplication"

<provider
            android:name="androidx.startup.InitializationProvider"
            android:authorities="${applicationId}.androidx-startup"
            tools:node="remove">
        </provider>

在应用程序构建 gradle 文件中:

    implementation "androidx.work:work-runtime-ktx:2.7.0"
    implementation("androidx.hilt:hilt-work:1.0.0")
    kapt("androidx.hilt:hilt-compiler:1.0.0")
    kapt "com.google.dagger:hilt-android-compiler:2.39.1"

在 MainApplication 类:

 @Inject
    lateinit var workerFactory: HiltWorkerFactory

 override fun onCreate() {
        super.onCreate()
               
        context = applicationContext
        WorkManager.initialize(this, workManagerConfiguration)


    }
     override fun getWorkManagerConfiguration() =
        Configuration.Builder()
            .setWorkerFactory(workerFactory)
            .build()

    companion object {
        lateinit var context: Context

    }
}

我的定期工人班级:

@HiltWorker
class PeriodicWorker @AssistedInject constructor(
    @Assisted appContext: Context, @Assisted workerParams: WorkerParameters,
    val repository: Repository
) : Worker(appContext, workerParams){

    override  fun doWork(): Result {
        try {

            val applicationContext = applicationContext
            // do nceessary work
            return Result.success()


        } catch (e: Exception) {

            Log.e("UploadWorker", e.printStackTrace().toString())
            return Result.failure()
        }
    }



}

在活动类中初始化周期性工作者:

  private lateinit var periodicWorkRequest: WorkRequest
override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        periodicWorkRequest = PeriodicWorkRequestBuilder<PeriodicWorker(15, TimeUnit.MINUTES)
        .build()
                
 WorkManager.getInstance(applicationContext).enqueue(periodicWorkRequest)

    }

【讨论】:

  • 非常感谢您发布您的工作代码,我不敢相信整个问题是由 Worker 类上缺少 @HiltWorker 注释引起的!在后台。 WorkManager 在 LogCat 上正确地触发了NoSuchMethodException,直到我查看了您的工作代码我才发现。非常感谢,你是传奇!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2023-03-03
  • 2022-06-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多