我正在编写我的第一个 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
与服务通信有三种明显的方式:
在您的情况下,我会选择选项 3。对其自身的服务进行静态引用并将其填充到 onCreate() 中:
void onCreate(Intent i) { sInstance = this; }
制作一个静态函数MyService getInstance(),它返回静态sInstance。
MyService getInstance()
sInstance
然后在Activity.onCreate()您启动服务时,异步等待服务实际启动(您可以让您的服务通过向 Activity 发送意图来通知您的应用程序已准备好。)并获取其实例。当您拥有实例时,将您的服务侦听器对象注册到您的服务并设置好。注意:在 Activity 中编辑视图时,您应该在 UI 线程中修改它们,服务可能会运行自己的线程,因此您需要调用Activity.runOnUiThread().
Activity.onCreate()
Activity.runOnUiThread()
您需要做的最后一件事是删除对您的侦听器对象的引用Activity.onPause(),否则您的活动上下文的实例将泄漏,不好。
Activity.onPause()
注意:此方法仅在您的应用程序/活动/任务是访问您的服务的唯一进程时才有用。如果不是这种情况,您必须使用选项 1. 或 2。