如何让 Android Service 与 Activity 通信 [英] How to have Android Service communicate with Activity

查看:30
本文介绍了如何让 Android Service 与 Activity 通信的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I'm writing my first Android application and trying to get my head around communication between services and activities. I have a Service that will run in the background and do some gps and time based logging. I will have an Activity that will be used to start and stop the Service.

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

So first, I need to be able to figure out if the Service is running when the Activity is started. There are some other questions here about that, so I think I can figure that out (but feel free to offer advice).

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

My real problem: if the Activity is running and the Service is started, I need a way for the Service to send messages to the Activity. Simple Strings and integers at this point - status messages mostly. The messages will not happen regularly, so I don't think polling the service is a good way to go if there is another way. I only want this communication when the Activity has been started by the user - I don't want to start the Activity from the Service. In other words, if you start the Activity and the Service is running, you will see some status messages in the Activity UI when something interesting happens. If you don't start the Activity, you will not see these messages (they're not that interesting).

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

It seems like I should be able to determine if the Service is running, and if so, add the Activity as a listener. Then remove the Activity as a listener when the Activity pauses or stops. Is that actually possible? The only way I can figure out to do it is to have the Activity implement Parcelable and build an AIDL file so I can pass it through the Service's remote interface. That seems like overkill though, and I have no idea how the Activity should implement writeToParcel() / readFromParcel().

有更简单或更好的方法吗?感谢您的帮助.

Is there an easier or better way? Thanks for any help.

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

For anyone who's interested in this later on, there is sample code from Google for handling this via AIDL in the samples directory: /apis/app/RemoteService.java

推荐答案

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

There are three obvious ways to communicate with services:

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

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

In your case, I'd go with option 3. Make a static reference to the service it self and populate it in onCreate():

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

创建一个静态函数MyService getInstance(),返回静态sInstance.

Make a static function MyService getInstance(), which returns the static sInstance.

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

Then in Activity.onCreate() you start the service, asynchronously wait until the service is actually started (you could have your service notify your app it's ready by sending an intent to the activity.) and get its instance. When you have the instance, register your service listener object to you service and you are set. NOTE: when editing Views inside the Activity you should modify them in the UI thread, the service will probably run its own Thread, so you need to call Activity.runOnUiThread().

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

The last thing you need to do is to remove the reference to you listener object in Activity.onPause(), otherwise an instance of your activity context will leak, not good.

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

NOTE: This method is only useful when your application/Activity/task is the only process that will access your service. If this is not the case you have to use option 1. or 2.

这篇关于如何让 Android Service 与 Activity 通信的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆