当应用程序被关闭时如何使WorkManager保持活动状态?

3
我使用“协程工作程序”下载文件。当应用在后台时,下载工作正常进行;但当应用被关闭时,工作管理器停止工作。
我尝试使用布尔变量在一个无限循环中使其保持运行以使其工作,但这也没有起作用。

class UploadWorker(
    private val appContext: Context,
    workerParams: WorkerParameters
) : CoroutineWorker(appContext, workerParams) {
    private var isDownloadCompleted = false


    override suspend fun doWork(): Result {
        val filName = inputData.getString("filName") ?: ""
        val url = inputData.getString("URL") ?: ""

        /*when file is downloaded, I change the status of the boolean to true, so it break the 
          loop*/

        //Loop break when download file is completed, occur error, or pause.
        while (!isDownloadCompleted) {
            Log.e("tag**", "downloaded file $isDownloadCompleted")
        }

        // Indicate whether the work finished successfully with the Result
        return Result.success()
    }

}


val imageData = workDataOf("URL" to url, "filName" to filName)
        val constraints = Constraints.Builder()
            .setRequiresBatteryNotLow(false)
            .setRequiredNetworkType(NetworkType.CONNECTED)
            .setRequiresStorageNotLow(false)
            .build()
        Log.e("tag**", "createReq")

        val uploadWorkRequest: WorkRequest =
            OneTimeWorkRequestBuilder<UploadWorker>()
                .setInputData(imageData)
                .setConstraints(constraints)
                .setInitialDelay(0, TimeUnit.SECONDS)
                .setBackoffCriteria(
                    BackoffPolicy.LINEAR,
                    OneTimeWorkRequest.MIN_BACKOFF_MILLIS,
                    TimeUnit.MILLISECONDS
                )
                .build()

我希望即使应用程序被杀死或在后台运行,它也能正常工作。


不理解问题,您是说即使应用程序被杀死,您仍然想执行下载操作吗? - M Ashhal
如果应用程序未被杀死或在后台运行,则文件将被下载,但如果应用程序被杀死,则不起作用。 WorkManager 应该即使应用程序被杀死也能正常工作。 - Ahmad Idrees
我认为这与您的工作请求有关,因为您的工作请求是时间请求,您可以尝试将其替换为PeriodicWorkRequest,它将在每个x时间后运行,而不管应用程序的状态如何(仅当应用程序未被强制关闭时)。 - M Ashhal
对于任何在应用程序被杀死时需要执行的任务,您需要创建前台服务,这是在应用程序被杀死或未在RAM中执行任务的唯一方法。 - Karan Mehta
@MAshhal,这个没有起作用,当应用程序从后台关闭时,工作管理器的执行停止,但是当我重新打开应用程序时,它的执行会从停止的地方开始。但是即使应用程序被强制关闭,它也必须继续工作。 - Ahmad Idrees
@KaranMehta 在 Work Manager 文档中,如果您不返回状态(成功或失败),工作管理器将永远不会停止。 - Ahmad Idrees
4个回答

0

所有的东西都很好,但我忘记在工作管理器中附加通知了。

class UploadWorker(
    private val appContext: Context,
    workerParams: WorkerParameters
) : CoroutineWorker(appContext, workerParams) {
    private var isDownloadCompleted = false


    override suspend fun doWork(): Result {
        notification = NotificationCompat.Builder(
            applicationContext,
            appContext.getString(R.string.channel_name)
        )
            .setSmallIcon(R.mipmap.ic_launcher)
            .setContentTitle(getString(R.string.app_name))
            .setContentText("0MB/ $fileSize")
            .setOnlyAlertOnce(true)
            .setProgress(100, 0, false)
            .setPriority(NotificationCompat.PRIORITY_MAX)
            .setOngoing(true)
            .setAutoCancel(false)
            .setDefaults(NotificationCompat.DEFAULT_ALL)
        
        
        val filName = inputData.getString("filName") ?: ""
        val url = inputData.getString("URL") ?: ""
        //attach your notification, so workmanager will be killed
        setForegroundAsync(ForegroundInfo(id, notification.build()))

        /*when file is downloaded, I change the status of the boolean to true, so it break the 
          loop*/

        //Loop break when download file is completed, occur error, or pause.
        while (!isDownloadCompleted) {
            Log.e("tag**", "downloaded file $isDownloadCompleted")
        }

        // Indicate whether the work finished successfully with the Result
        return Result.success()
    }

}

现在一切都按预期工作了吗? - radus14

0

请检查这是否对您有帮助 ->

Kotlin ->


class UploadWorker(
        private val appContext: Context,
        workerParams: WorkerParameters
    ) : CoroutineWorker(appContext, workerParams) {
        private var isDownloadCompleted = false


        override suspend fun doWork(): Result {
            val filName = inputData.getString("filName") ?: ""
            val url = inputData.getString("URL") ?: ""

            /*when file is downloaded, I change the status of the boolean to true, so it break the
              loop*/

            //Loop break when download file is completed, occur error, or pause.
            while (!isDownloadCompleted) {
                Log.e("tag**", "downloaded file $isDownloadCompleted")
            }

            // Indicate whether the work finished successfully with the Result
            return Result.success()
        }

    }

不要使用OneTimeWorkRequest,尝试使用PeriodicWorkRequest,希望它能够正常工作。

val imageData = workDataOf("URL" to url, "filName" to filName)
        val constraints = Constraints.Builder()
            .setRequiredNetworkType(NetworkType.CONNECTED)
            .setRequiresBatteryNotLow(false)
            .setRequiresStorageNotLow(false)
            .build()

        Log.e("tag**", "createReq")

        val uploadWorkRequest: WorkRequest =
            PeriodicWorkRequestBuilder<UploadWorker>(2, TimeUnit.HOURS)
                .setInputData(imageData)
                .setConstraints(constraints)
                .setInitialDelay(0, TimeUnit.SECONDS)
                .setBackoffCriteria(
                    BackoffPolicy.LINEAR,
                    OneTimeWorkRequest.MIN_BACKOFF_MILLIS,
                    TimeUnit.MILLISECONDS
                )
                .build()

我尝试过了,但是没有成功。当应用程序从后台关闭时,工作管理器的执行也会停止,而在重新打开应用程序时,它会从停止的位置开始执行。但是即使应用程序被杀死,它也必须正常工作。 - Ahmad Idrees

0

没有任何证据表明如果应用程序被杀死,WorkManager仍然可以工作。如果应用程序被杀死,它就死了。这就是全部。WorkManager确保的是:

  • 在执行Work时,应用程序不太可能被杀死,因为WorkManager会启动自己的服务
  • 如果应用程序被杀死并且相应的Work被停止 - WM将确保在稍后的阶段恢复Work,并在满足约束条件时一定会完成。

但是我们可以通过通知管理器来保持工作管理器的活动状态,它在Google Pixel和其他手机上运行良好,但不适用于Infinix、Redmi等手机。 - Ahmad Idrees

0

由于您正在使用oneTimeWorkRequest,请在构建工作请求时尝试使用setExpediated(true)。

注意:对于定期工作请求,无法设置setExpediated(true)。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接