小编典典

如何让 Android Service 与 Activity 通信

all

我正在编写我的第一个 Android 应用程序,并试图了解服务和活动之间的通信。我有一个服务将在后台运行并执行一些基于 GPS
和时间的日志记录。我将有一个用于启动和停止服务的活动。

所以首先,我需要能够确定 Activity 启动时服务是否正在运行。这里还有一些其他问题,所以我想我可以弄清楚(但随时提供建议)。

我真正的问题:如果 Activity 正在运行并且服务已启动,我需要一种方法让服务向 Activity 发送消息。此时是简单的字符串和整数 -
主要是状态消息。这些消息不会定期发生,所以如果有其他方法,我认为轮询服务不是一个好方法。我只希望在用户启动 Activity 时进行这种通信 -
我不想从服务启动 Activity。换句话说,如果您启动 Activity 并且 Service 正在运行,当发生一些有趣的事情时,您会在 Activity
UI 中看到一些状态消息。如果您不启动 Activity,您将看不到这些消息(它们不是那么有趣)。

似乎我应该能够确定 Service 是否正在运行,如果是,则将 Activity 添加为侦听器。然后在 Activity 暂停或停止时将 Activity
作为监听器移除。这真的可能吗?我能想到的唯一方法是让 Activity 实现 Parcelable 并构建一个 AIDL
文件,这样我就可以通过服务的远程接口传递它。不过,这似乎有点过头了,我不知道 Activity 应该如何实现 writeToParcel() /
readFromParcel()。

有没有更简单或更好的方法?谢谢你的帮助。

编辑:

对于以后对此感兴趣的任何人,Google 提供了示例代码,用于通过示例目录中的 AIDL
处理此问题:/apis/app/RemoteService.java


阅读 229

收藏
2022-05-16

共1个答案

小编典典

与服务通信有三种明显的方式:

  1. 使用意图
  2. 使用 AIDL
  3. 使用服务对象本身(作为单例)

在您的情况下,我会选择选项 3。对其自身的服务进行静态引用并将其填充到 onCreate() 中:

void onCreate(Intent i) {
  sInstance = this;
}

制作一个静态函数MyService getInstance(),它返回静态sInstance

然后在Activity.onCreate()您启动服务时,异步等待服务实际启动(您可以让您的服务通过向 Activity
发送意图来通知您的应用程序已准备好。)并获取其实例。当您拥有实例时,将您的服务侦听器对象注册到您的服务并设置好。注意:在 Activity
中编辑视图时,您应该在 UI 线程中修改它们,服务可能会运行自己的线程,因此您需要调用Activity.runOnUiThread().

您需要做的最后一件事是删除对您的侦听器对象的引用Activity.onPause(),否则您的活动上下文的实例将泄漏,不好。

注意:此方法仅在您的应用程序/活动/任务是访问您的服务的唯一进程时才有用。如果不是这种情况,您必须使用选项 1. 或 2。

2022-05-16