【问题标题】:Benefit of LocalService?LocalService 的好处?
【发布时间】:2012-03-15 21:59:52
【问题描述】:

我阅读了有关 AsyncTasks、Services、... 很清楚远程服务的用途。但是我遇到了麻烦,获得了 LocalService 的好处?典型的例子是“播放音乐”或下载大文件。但是我为什么要为此启动本地服务呢?

我做了一个小的 Async 任务,模拟这样一个任务。

AsyncTask<String, Integer, String> async = new AsyncTask<String, Integer, String>() {
            @Override
            protected String doInBackground(String... params) {
                for (int i = 0; i < 100; i++) {
                    try {
                        Thread.sleep(500);
                        System.out.println(i);
                    } catch (InterruptedException e1) {
                        e1.printStackTrace();
                    }
                }

                return null;
            }
        };
        async.execute("");

大多数答案是,(本地)服务用于长时间运行的活动,即使在主要活动关闭时也必须运行。好的 - 但我也可以在主活动中使用异步任务来做到这一点:

Button btnFinish = (Button) findViewById(R.id.button1);
        btnFinish.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                finish();
            }
        });

按下按钮调用 onDestroy(),但 Async 任务仍在运行?那么这和从 Service 启动 AsyncTask 不一样吗?

//编辑: 我进行了几次测试,我很确定异步任务的存在时间与 process 一样长。因此,如果我将它包装到本地服务中(常用方式) - 它也会与流程一样长......

那么为什么每个人都使用本地服务来完成诸如下载文件、同步等任务呢?!

【问题讨论】:

  • 服务的优势在于它与您的活动生命周期无关 - groups.google.com/group/android-developers/browse_thread/thread/…
  • 异步任务也不是 - 请参阅我的示例。我完成了 Activity 并且 Task 仍在运行...
  • 是的,但是一旦完成,您将无法更新任何 UI。这可能会出现问题。
  • 一般来说,问题不在于怎么做,而是怎么做更合理,Service有针对特定用例的特定设计, 这可能不适合 Activity。以 HttpClient 为例,你绝对可以在每个活动中按需创建新的 HttpClient。使用服务创建一个 HttpClient 并将所有与 http 相关的代码维护在一个中心位置会更有效和合理。可以从许多活动中重复使用。 IMO 我会将 Service 视为 MVC 中的 C,尽管它也可以做 UI 的事情。

标签: android android-asynctask android-service


【解决方案1】:

大多数答案是,(本地)服务用于长时间运行的活动,即使在主要活动关闭时也必须运行。好的 - 但我也可以在主活动中使用异步任务来做到这一点:

并非没有内存泄漏。永远不要从组件中泄漏线程。当一个活动被销毁时,确保由该活动启动的所有线程将快速关闭。

我进行了几次测试,我很确定异步任务的存在时间与进程一样长。

正确。但是,如果没有服务,则在用户离开前台 Activity 并转到其他应用程序后,该进程可能只存在几毫秒。

服务是一个标记,告诉 Android “哟!我还在这儿工作,哟!”。这个标记不能让进程无限期地保持活动状态,但它通常适用于将要运行几分钟或几小时的事情。

服务有自己的生命周期,独立于活动。例如,如果你想每 15 分钟控制一次做一些工作,正确的解决方案是使用AlarmManager 和一个IntentService,而这个应用程序周围可能没有任何活动。

那么为什么每个人都使用本地服务来完成下载文件、同步等任务

因为我们希望它正常工作。

【讨论】:

  • 我可以使用:应用程序 1 -> 活动 A -> 启动 AsyncTask。应用程序 2 -> 活动 B -> 启动服务 S -> 启动异步任务。如果我关闭两个应用程序 (finish() ),应用程序 1 会被杀死吗?因为服务 S 使应用程序保持“活动”(操作系统的优先级更高)?!
  • @JohannesStaehlin:如果我正确理解您的情况,应用程序 1 的进程将在应用程序 2 的进程之前终止。如何快速终止应用程序 1 的进程取决于很多事情,例如设备还发生了什么以及用户接下来要做什么。应用程序 1 的进程可能存在几毫秒或几小时——你只是不知道。
  • 好的,但重要的是我们不知道。在 App2 中:只要我们有一个服务在运行,进程通常不会被杀死。
  • @JohannesStaehlin:App2 的进程不会永远存在,因为有太多草率的开发人员启动服务并且从不停止服务。 App2 的进程将比 App1 的进程寿命更长。
【解决方案2】:

按照我的理解,AsyncTask 的预期用途更符合在一些后台处理发生后更新您的 UI。这个想法是,当它们完成后,您可以在 UI 线程上执行一些操作。您建议像服务一样使用它们的方式类似于盲目地将 Runnable 排队并让它在后台线程上运行,直到其处理完成,完全独立于 Activity 生命周期的其余部分。通常,人们会在 onPause 或 onDestroy 中取消这些额外的挂起线程。否则这样做是不好的形式,因为它们可能会导致错误,即使在您的 Activity 关闭后也会向用户显示崩溃对话框。

您可以将本地服务用于长时间运行的任务,这些任务不需要能够向用户显示某些内容的上下文,或者独立于应用程序中的任何 Activity 的任务。除非应用程序本身被杀死,否则系统将知道不会杀死您的服务(这是将其绑定到活动的好处)。它们也比远程服务更简单,不需要进程间通信或额外的进程。您可能还希望有一个服务,如果从其他地方调用(本地服务)会触发您的应用程序启动,或者如果您的应用程序死亡,它会终止。远程服务可以在您的应用程序上下文之外运行,因此与您的应用程序的生命周期无关。

【讨论】:

  • 另外,请看这里:anddev.org/remote_service_tutorial-t8127.html 这篇文章还提供了本地服务的链接,详细说明了两者之间的一些差异,但更重要的是,它们提供了一些使用远程或本地服务的用例和理由,分别。
猜你喜欢
  • 2018-01-20
  • 2013-10-10
  • 2010-11-21
  • 2015-02-19
  • 2010-11-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多