当前位置: 首页 > 知识库问答 >
问题:

如何将Rxjava用于长时间运行的后台任务

杜曜灿
2023-03-14

我正在使用rxjava将一些任务上载到服务器,每当任务启动的片段或活动被销毁时,我都会处理订阅以避免内存泄漏,但我想要的是,即使在片段/活动被销毁后,我也需要继续在后台运行任务,有什么方法可以实现这一点吗?

实例

doSomeLongRunningBgTaks()
     .subscribe()
     .addTo(compositeDisposal)
override onDestroy(){
  compositeDisposal.clear()
}

是否必须始终释放订阅?如果不是,何时使用dispose?

共有3个答案

颜乐
2023-03-14

您可以使用以下内容:

webService.doSomething(someData)
      .observeOn(AndroidSchedulers.mainThread())
      .subscribe(
          result -> resultText.setText("It worked!"),
          e -> handleError(e));
戚研
2023-03-14

那么为什么你需要一次性的?

所以如果你有一些可观察到的,比如下面:

Observable.just("Hello world!")
     .delay(1, TimeUnit.SECONDS)
     .subscribeWith(new DisposableObserver<String>() {
         @Override public void onStart() {
             System.out.println("Start!");
         }
         @Override public void onNext(String t) {
             System.out.println(t);
         }
         @Override public void onError(Throwable t) {
             t.printStackTrace();
         }
         @Override public void onComplete() {
             System.out.println("Done!");
         }
     });

现在,如果您想停止此任务,则仅通过dispose()将其释放。

如果用户希望处理任何任务,例如:如果用户从屏幕导航或用户按下后退按钮,则我们必须终止web请求或取消任何任务,此时将使用一次性任务。

如果您必须在后台执行任何任务,并且在片段被销毁时不杀死,该怎么办?

您可以简单地使用write only subscribe()方法,而忘记了任务。

doSomeLongRunningBgTaks()
     .subscribe()

也许能帮到你谢谢

班思源
2023-03-14

首先,您必须了解现代版本AndroidOS的后台任务限制。所有关于它的信息[链接](https://developer.android.com/about/versions/oreo/background)简而言之,如果你的应用程序不可见,或者你的应用程序没有正在运行的前台服务,那么就不能保证你的后台工作已经完成。

其次,在您的情况下,您需要有一些实体,它与您的片段或活动的任何生命周期无关,并且能够运行后台工作。有几种可能的解决方案

1)Android服务方式

创建一个Intent服务。这是一个简单的服务,具有已实现的块,具有内部队列。每次客户端尝试通过此类服务执行作业时,服务都会在后台队列中执行此类任务。因此,如果您执行两次,该服务将在执行第二个任务之前等待第一个任务完成。

导入android。应用程序。IntentService导入android。所容纳之物意图

class MyIntentService : IntentService("My intent service") {

  // This method already in another thread (not UI thread)
  override fun onHandleIntent(intent: Intent?) {
    doLongRunningBackgroundJob()
  }
}

附言:不要忘记在清单文件中注册此类服务。

2) Android处理程序方式

您可以使用带有准备好的后台循环器的内部android处理程序创建一个类。例如:

import android.os.Handler
import android.os.HandlerThread

class MyBackgroundWorker {

  private val handler = initHandler()

  private fun initHandler(): Handler {
    val handlerThread = HandlerThread("My background thread")
    handlerThread.start()
    return Handler(handlerThread.looper)
  }

  fun executeJobInBackground(job: Runnable) {
    handler.post(job)
  }
}

3) 纯java方式

您可以创建纯线程的实例,但更可取的是使用执行器Java框架。对于线程方法:

class MyBackgroundWorker {

  fun executeJobInBackground(job: Runnable) {
    Thread(job).start()
  }
}

对于执行者方法:

import java.util.concurrent.Executors

class MyBackgroundWorker {

  private val executor = Executors.newSingleThreadExecutor()

  fun executeJobInBackground(job: Runnable) {
    executor.execute(job)
  }
}

P、 不要忘记使用DI方法提供依赖关系。

 类似资料:
  • 我正在尝试将一个向服务器发送消息的异步任务迁移到RxJava。该任务大致执行以下操作: 1) 创建将要发送的消息(保存到数据库) 2)向用户显示消息(状态为“发送”) 3)将消息发送到服务器(下面的代码段) 4)将消息标记为已发送或失败(保存到数据库) 5)更新UI 我创建了所需的Rx链,部分如下所示: 当我订阅上述内容时,我会得到一个一次性的。通常,我会将其添加到CompositeDisposa

  • Android系统如何处理长时间运行的后台任务?开发人员能否依赖系统保持活动的未绑定服务?

  • 我有一个压缩图像的任务,它在图像中使用了许多循环: 我在普通线程中运行此方法,如下所示: 或者在后台工作线程中运行 问题是:这种方法有时会出错,在接收无效输入时会导致无限循环。在这种情况下,它将永远运行,并损害CPU,即使当设备的屏幕关闭时,这会增加设备的温度(如果我使用工作线程,它还会阻止等待队列中的其他任务)。 我想我需要设置一个超时来终止长时间运行的任务。在正常Java线程中实现这一点的最佳

  • 问题内容: 我有一个运行长时间运行的作业的Web服务(大约几个小时)。我正在使用Flask,Gunicorn和nginx进行开发。 我正在考虑做的事情是拥有一条需要很长时间才能完成的路由,调用一个创建线程的函数。然后,该函数将向路径返回一个GUID,并且路径将返回一个URL(使用GUID),用户可以使用该URL来检查进度。我正在将线程设为守护程序(thread.daemon = True),以便如

  • 我试着运行我的第一个颤振项目,但我不断地得到这个错误。 失败:构建失败,有一个异常。 > 哪里出错了:配置根项目'android'时出现问题。 无法解析配置“:classpath”的所有项目。无法下载gradle。jar(com.android.tools.build:gradle:3.5.0)无法获取资源的https://dl.google.com/dl/android/maven2/com/a

  • 我正在使用Flexible App Engine和Python3构建一个应用程序。在标准appEngine中,如果您需要运行超过60的任务,您可以使用task队列或我成功完成的延迟库(任务队列的抽象)。 Flexible App Engine不再支持包含这些函数的appengine api。相反,功能正在迁移到谷歌云库(https://googlecloudplatform.github.io/g