【问题标题】:How do I notify Workmanager task completed to Service?如何将 Workmanager 任务完成通知服务?
【发布时间】:2020-09-25 09:12:22
【问题描述】:

我的 Worker(用于 API 调用)从服务开始,我想将完成事件发送到服务类。 最好的方法应该是什么?

服务调用:

PeriodicWorkRequest request = new PeriodicWorkRequest
                .Builder(Worker.class, Constants.REPEAT_INTERVAL, TimeUnit.MINUTES)
                .addTag(TAG)
                .setConstraints(new Constraints.Builder().setRequiredNetworkType(NetworkType.CONNECTED).build())
                .build();
        WorkManager.getInstance(getApplicationContext()).enqueue(request);
    

从 WorkManager 调用:

override fun doWork(): Result {
    // API call
    return Result.success()
}

【问题讨论】:

  • 你在使用协程吗?
  • 没有@MariuszBrona
  • 你能描述一下对象之间的联系吗?
  • @MariuszBrona,请查看更新后的问题。

标签: android android-service android-workmanager


【解决方案1】:

好的,我要做的是为 Worker 和 Service 类创建公共对象并利用观察者模式。这个WorkObserver 对象将充当 Service 和 Worker 之间的代理。以 Koin 为例,它看起来像这样:

class MyWorker: Worker(), KoinComponent {

    private val workObserver: WorkObserver by inject()

    override fun doWork(): Result {
        val result = api.call().execute()
        if(result.isSuccessful) {
            workObserver.notifySuccess()
            return Result.success()
        } else {
            workObserver.notifyError()
            return Result.failure()
        }
    }

}

class MyService: Service(), KoinComponent {

    private val workObserver: WorkObserver by inject()

    override fun onCreate() {
        workObserver.setOnResultListener { result ->
            if(result) {
                //do something
            } else {
                // do something else
            }
    }

    override fun onDestroy() {
        workObserver.setOnResultListener(null)
    }
}

class WorkObserver {

    private var onResultListener: ((Result) -> Unit)? = null

    fun setOnResultListener(listener: ((Result) -> Unit)?) {
         this.onResultListener = listener
    }

    fun notifySuccess() {
        this.onResultListener?.invoke(true)
    }

    fun notifyError() {
        this.onResultListener?.invoke(false)
    }
}

当然,您可以使用其他 DI 工具,您可以拥有一个侦听器列表并删除特定的侦听器,您可以通过 WorkObserver 中的侦听器传递任何其他对象以及您需要的有效负载。我刚刚创建了一个简单的布尔传递

但是,对于这种简单的情况,如果您不想使用 DI,简单的 Object 就可以完成这项工作。但是,当您的代码库增长并且您正在处理多线程问题,或者甚至在应用程序的其他部分访问此对象时,它可能会导致问题。我只使用它在对象之间传递信息,我不建议使用它来存储数据等:

class MyWorker: Worker() {

    override fun doWork(): Result {
        val result = api.call().execute()
        if(result.isSuccessful) {
            WorkObserver.notifySuccess()
            return Result.success()
        } else {
            WorkObserver.notifyError()
            return Result.failure()
        }
    }

}

class MyService: Service() {

    override fun onCreate() {
        WorkObserver.setOnResultListener { result ->
            if(result) {
                //do something
            } else {
                // do something else
            }
    }

    override fun onDestroy() {
        WorkObserver.setOnResultListener(null)
    }
}

object WorkObserver {

    private var onResultListener: ((Result) -> Unit)? = null

    fun setOnResultListener(listener: ((Result) -> Unit)?) {
         this.onResultListener = listener
    }

    fun notifySuccess() {
        this.onResultListener?.invoke(true)
    }

    fun notifyError() {
        this.onResultListener?.invoke(false)
    }
}

【讨论】:

  • 你有其他没有DI的解决方案吗?
  • 嘿,现在检查一下
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-02-06
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多