【问题标题】:About android service-activity data transceive and ServiceConnection关于android service-activity 数据收发和ServiceConnection
【发布时间】:2013-11-30 04:02:47
【问题描述】:

有几种方法可以将 Service 连接到 Activity。我只对本地服务感兴趣,我的LocalService 将站在那里直到用户停止它(这也意味着应用程序结束)。我可能知道有问题,如果有,请纠正我。

reference page上写着要直接使用本地服务的方法,应该使用ServiceConnection。绑定后,我们就可以有一个LocalService类的引用,我们可以直接使用这个LocalService的方法。 AFAIK 我们使用此引用调用的方法在具有相关 Activity 的主线程上运行。

让我感到困惑的是,如果我使用骨架结构并直接通过其静态引用(即通过LocalService.getInstance())访问LocalService 的方法会怎样。嗯,我已经用过,没有遇到任何问题,但我仍然不确定哪个更好,为什么。

提前致谢。如果需要,我可能会添加其他信息。

编辑: 在我之前提到的解决方案中,没有任何活动保留对LocalService 的引用。

习惯了

  1. 启动一些LongRunningAsyncTasks(在服务停止之前全部停止并且引用无效),
  2. 更新应用Notification
  3. 获取getFilesDir(),
  4. 保留枚举值(其引用未保存在其他地方,仅用于比较)以便从任何地方访问(不值得使用 SharedPreferences)。
  5. 展示一些祝酒词

【问题讨论】:

    标签: android android-service serviceconnection


    【解决方案1】:

    注意活动和服务的静态引用,因为它们可能是内存泄漏的原因。如果您不希望您的服务在主进程中运行,则将其提取到另一个进程并使用服务连接。

    如果您不需要服务的任何反馈,那么就不要使用连接,而只需使用startService() 和几个命令,这些命令将在服务的onStartCommand() 方法中执行。

    如果您需要来自服务的反馈,但不是很频繁,则使用startService() 并通过sendBroadcast() 或通过 Handler 类从服务获得反馈。

    如果您需要频繁反馈(例如更新媒体播放器的滑块),那么最好使用服务连接。

    请记住,您的服务可以在不执行 onDestroy() 方法且没有任何通知的情况下随时终止,这就是为什么保持静态引用不是一个好主意。

    【讨论】:

    • 我的服务不需要额外的流程(我只对LocalService感兴趣)。我不保留对服务的引用(始终由它使用 getInstance();),并且该实例在服务停止时被清空。这有什么改变吗?
    • 您在活动中交付实例,当您的服务即将终止时,对这个实例的引用仍然存在 - 猜猜在哪里?
    • 除了一些 LongRunningTasks 之外,我看不到任何地方,它们甚至在服务停止之前就已终止。他们的引用也被取消了。我在做一些比平常更完美的事情吗?或者我们无法完全理解对方(我更喜欢第二个,因为我的英语/机器人很弱)。
    • 我猜你是在 onDestroy() 方法中将实例归零,该方法不是每次都调用。您的服务可以简单地被操作系统杀死并且不会调用 onDestroy() 方法。因此参考将保留。如果你想使用静态实例,那么至少使用类 WeakReference。
    • 感谢 WeakReference 的提议,除了我在 selfStopping 之前清空实例。
    【解决方案2】:

    从您所说的看来,您可能根本不需要服务。看起来您没有在 LocalService 中执行任何长期任务。如果是这种情况,您也可以使用 AsyncTask 或 Handlers 并完成。使用服务(本地或其他)的动机是在其中执行一些长期存在的任务,而不是停止主 UI 线程。如果您的任务不会占用太多时间,那么您就不需要服务。

    服务默认在主线程上运行。除非它是自动为您创建工作线程的 IntentService,并且所有任务都在此工作线程中排队并一次处理一个。否则,您有责任为您的服务任务创建一个单独的线程。

    所以,首先分析您是否真的需要服务。如果您的任务可以快速执行,那么即使有服务也不要费心。

    希望对您有所帮助。

    【讨论】:

    • LongRunningAsyncTasks 最少需要 4-5 秒,有些需要 5-10 分钟。我想我需要一些服务,不是吗?
    • 是的,超过 4 秒,建议让它在另一个线程(Service 或 AsyncTasks 或 Handlers)上运行。
    • 那么,您的问题主要是为什么不能直接使用对 Service 对象的静态引用,是吗?
    • 我知道一些其他情况(RemoteService 等),但在我的情况下,是的,你可以这么说。
    • @bluebrain Autocrab 是在正确的轨道上。您的应用程序运行的进程可以在系统处于后台时随时终止/终止。因此,拥有静态引用会导致内存泄漏。
    猜你喜欢
    • 1970-01-01
    • 2023-03-08
    • 1970-01-01
    • 2013-01-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-04-14
    • 1970-01-01
    相关资源
    最近更新 更多