2

我有一个应用程序在打开启动设备时运行某些“长时间”进程。

该进程通过下载管理器执行一定数量的下载,当进程完成时,它会向应用程序发送一个广播事件,以捕获一些分析。

据我了解,每当调用引导广播事件时,都会Application实例化该类(如果尚未在内存中)。

Application当用户打开应用程序时,也会启动类。

基于此,运行进程的代码被放置在类onCreate的方法中Application。(进程从那里开始一个新线程)

但是,似乎“长”进程花费的时间超过了启动广播接收器的生存时间(大约 10 秒?),因此应用程序进程被终止。然后几秒钟后,在下载完成后,发送了第二个广播,并且应用程序再次开始再次调用Application.onCreate,但产生了一些不良影响。

该进程预计将以单一线性方式运行,并且不会再次调用onCreate

由于这个过程只发生一次,我正在考虑创建一个Service给应用程序更多的时间来保持活力。但是该过程取决于 DownloadManager 所以:

1)使用IntentService将不起作用(据我所知),因为该过程在handleIntent返回后仍然被杀死。该进程创建新线程,因此其任务是异步的,并且handleIntent方法将在整个进程完成之前返回。

2)我应该创建一个Service简单地“活着”一段时间然后在进程完成后停止的吗?

3)作为一个额外的问题,如果我有一个 running ServiceApplication类会被实例化并保存在内存中,直到服务停止?

4

2 回答 2

1

如果您只这样做一次,您应该创建自己的Service. 当您的应用启动时,调用startService(). 在onStartCommand()您的Service中,启动一个Thread执行您想要的操作并返回的背景START_STICKY(这会保持您的Service运行,直到您停止它)。完成后,Thread调用stopSelf().Service

当然,您可以使用IntentService,但该类只是Service为您提供另一层便利的扩展。管理一个后台线程池,并在它耗尽工作时IntentService负责启动和停止。Service对于您需要的东西,这可能有点矫枉过正,但如果您愿意,可以继续使用它。这里的权衡可以忽略不计。

注意:<opinion>出于某种原因,许多开发人员似乎喜欢某些“时尚”的解决方案,例如AsyncTaskIntentService和 Event Bus。还有很多其他方法可以解决问题。软件开发中没有“一刀切”。</opinion>

于 2016-12-22T07:14:12.157 回答
0

您仍然可以使用 Intent 服务,您只需要在后台任务运行时阻止。实现可以像这样工作:

把它放在一个服务中,一个 IntentService 可以像这样工作:

 public class DownloadIntentService extends IntentService { 

  @Override
  protected void onHandleIntent(Intent intent) {
     //get url or whatever from intent
     //kick off async code to start the download, something like eg:
      DownloadTask downloadTask = new DownloadTask(url);
      downloadTask.setListener(new Listener() {
          public void onComplete(Download download) {
              DownloadIntentService.this.notify();
          }
       }
       downloadTask.start()
       wait();

  }
于 2016-12-16T21:38:06.513 回答