gpt4 book ai didi

android - WorkManager两次启动Worker

转载 作者:行者123 更新时间:2023-12-02 13:36:33 26 4
gpt4 key购买 nike

我有一组大型任务要在后台执行:

  • 住宿数据
  • 解析一堆文件并将其存储在Room


  • 因此,我使用相同的 Worker创建了独特的 tag链。
    class GtfsStaticManager() {
    private val workerManager = WorkManager.getInstance()

    override fun load() {
    val constraints = Constraints.Builder().setRequiredNetworkType(NetworkType.CONNECTED).build()

    val inputData = GtfsStaticLoadDataWorker.inputData(staticUrl, cacheDir)
    // 1. Loading data
    val downloadWorkRequest = OneTimeWorkRequest.Builder(GtfsStaticLoadDataWorker::class.java)
    .addTag("GTFS")
    .setConstraints(constraints)
    .setInputData(inputData)
    .build()

    // 2. List of Workers to parse and store data to the Room
    val parseWorkers = GtfsFile.values().map {
    OneTimeWorkRequest.Builder(GtfsStaticParseFileWorker::class.java)
    .setInputData(GtfsStaticParseFileWorker.inputData(it.file, cacheDir + File.separator + "feed"))
    .addTag("GTFS")
    .build()
    }

    workerManager
    .beginUniqueWork("GTFS", ExistingWorkPolicy.KEEP, downloadWorkRequest)
    .then(parseWorkers)
    .enqueue()
    }
    }

    除一件事情外,其他所有东西都工作正常:其中一个文件具有400万条记录,大约需要10-15分钟才能完成。一段时间后,我注意到它又重新加入了队列 ,但第一个作业仍在运行,因此结果是我有2个巨大的作业在后台运行,当然我的数据已被复制。

    我遵循了codelabs教程,我错过了什么吗?

    下面是我的带有解析逻辑的Worker:
    class GtfsStaticParseFileWorker(
    context: Context,
    workerParameters: WorkerParameters
    ) : Worker(context, workerParameters) {
    private val fileName: String get() = inputData.getString(FILE_NAME) ?: ""
    private val cacheDir: String get() = inputData.getString(UNZIP_FOLDER) ?: ""

    companion object {
    private const val FILE_NAME = "FILE_NAME"
    private const val UNZIP_FOLDER = "UNZIP_FOLDER"
    fun inputData(fileName: String, cacheDir: String) = Data
    .Builder()
    .putString(FILE_NAME, fileName)
    .putString(UNZIP_FOLDER, cacheDir)
    .build()
    }

    override fun doWork(): Result {
    val db = LvivTransportTrackerDataBase.getUpdateInstance(applicationContext)
    val agencyRepository = AgencyRepository(db.agencyDao())
    val calendarRepository = CalendarRepository(db.calendarDao())
    val calendarDateRepository = CalendarDateRepository(db.calendarDateDao())
    val routeRepository = RouteRepository(db.routeDao())
    val stopTimeRepository = StopTimeRepository(db.stopTimeDao())
    val stopRepository = StopRepository(db.stopDao())
    val tripRepository = TripRepository(db.tripDao())

    val file = File(cacheDir + File.separator + fileName)
    val fileType = GtfsFile.from(fileName) ?: return Result.failure()

    when (fileType) {
    GtfsFile.Agency -> agencyRepository.deleteAll()
    GtfsFile.CalendarDates -> calendarDateRepository.deleteAll()
    GtfsFile.Calendar -> calendarRepository.deleteAll()
    GtfsFile.Routes -> routeRepository.deleteAll()
    GtfsFile.StopTimes -> stopTimeRepository.deleteAll()
    GtfsFile.Stops -> stopRepository.deleteAll()
    GtfsFile.Trips -> tripRepository.deleteAll()
    }

    FileInputStream(file).use { fileInputStream ->
    InputStreamReader(fileInputStream).use inputStreamReader@{ inputStreamReader ->
    val bufferedReader = BufferedReader(inputStreamReader)
    val headers = bufferedReader.readLine()?.split(',') ?: return@inputStreamReader
    var line: String? = bufferedReader.readLine()

    while (line != null) {
    val mapLine = headers.zip(line.split(',')).toMap()

    Log.d("GtfsStaticParse", "$fileType: $line")
    when (fileType) {
    GtfsFile.Agency -> agencyRepository.create(AgencyEntity(mapLine))
    GtfsFile.CalendarDates -> calendarDateRepository.create(CalendarDateEntity(mapLine))
    GtfsFile.Calendar -> calendarRepository.create(CalendarEntity(mapLine))
    GtfsFile.Routes -> routeRepository.create(RouteEntity(mapLine))
    GtfsFile.StopTimes -> stopTimeRepository.create(StopTimeEntity(mapLine))
    GtfsFile.Stops -> stopRepository.create(StopEntity(mapLine))
    GtfsFile.Trips -> tripRepository.create(TripEntity(mapLine))
    }

    line = bufferedReader.readLine()
    }
    }
    }

    return Result.success()
    }
    }

    附言我的依赖是implementation "android.arch.work:work-runtime:1.0.0"

    最佳答案

    在WorkManager中,工作程序类的执行限制为10分钟。
    WorkManager guide on how to handle cancellation:

    The system instructed your app to stop your work for some reason. This can happen if you exceed the execution deadline of 10 minutes. The work is scheduled for retry at a later time.



    在您的情况下,您没有处理工作的停止,但是WorkManager将忽略任何结果,因为它将作业标记为“已取消”,并在可能的情况下再次执行。

    这可能会导致您遇到双重执行。

    在不进一步了解您要实现的目标的情况下,很难提出另一种方法,但是,作为一般规则,WorkManager适用于需要保证执行的可延期任务。

    WorkManager documentation在1.0版本之后进行了扩展,您可以在此处找到更多信息。

    关于android - WorkManager两次启动Worker,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55383105/

    26 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com