Android 从 Service 到 Client 的通信

Posted

技术标签:

【中文标题】Android 从 Service 到 Client 的通信【英文标题】:Android communicating from Service to Clients 【发布时间】:2019-10-01 21:59:01 【问题描述】:

我想保留对绑定到已启动和绑定的 android 服务的每个客户端的引用。我的服务不在单独的进程中。

我可以绑定多个客户端,例如- 1 个活动和 2 个片段。他们可能都对从服务返回的不同事件的组合感兴趣。理想情况下,我想在每个客户端绑定时向服务注册,然后遍历每个连接的客户端并向每个客户端发送消息。

现在我正在使用 Binder 将服务的 API 公开给客户端,但我不喜欢使用广播将数据从服务发送回客户端。感觉很“松”。想知道是否有更简洁和结构化的方法?

Message Handler 是一种方式,但我觉得我会丢失客户端当前访问服务 API 的 binder API。

【问题讨论】:

【参考方案1】:

绑定服务方法详述here 是合适的。你不必担心Handlers,甚至Intents(一旦绑定了客户端)。

参考给定链接中的示例:您可以简单地将功能添加到LocalService 对象,例如,

/** method for clients */
public int getRandomNumber() 
  return mGenerator.nextInt(100);


private Set<MyEventListener> mListeners = new HashSet<>();

/** A MyEventListener (your Activity, Fragment, etc.) calls this in its
 * onServiceConnected() method, on the reference it gets from getService(). */
public void registerListener(MyEventListener listener)

    mListeners.add(listener);


public void sendEvent()

    for(MyEventListener listener : mListeners)
    
         listener.onEvent();
    

...等等。所有方法在 UI 线程上同步执行。保证所有对象(Services 和客户端 (MyEventListener))的生命周期至少与 ServiceConnection 一样长。此外,在您明确解除绑定之前,ServiceConnection 不会遇到 onServiceDisconnected() 调用,因为您使用的是进程内服务。

【讨论】:

我确实考虑过这一点,但后来我觉得我需要另一种方法来“removeListener()”。而且,真的不希望每个客户都担心这一点。我的服务可能会充满不再活跃的侦听器,因为这是一项长期运行的服务。我该如何处理? 您应该更详细地说明您对removeListener() 方法的反对意见。如果Service 将在客户离开时被告知,则必须告诉它。如果代码重用是一个问题,那么也许你应该考虑创建一个Fragment/Activity 子类,它会自动绑定到服务并管理监听器生命周期。 原因是任何其他绑定到服务并注册其侦听器的开发人员都必须天生就知道他们也需要取消注册。 如果您在不同的进程中谈论 3rd 方客户端,这将不起作用。 再一次,正确编写的子类可以强制执行这些生命周期规则。但是,如果这对您的用例来说确实不合理,您可以只使用弱引用。请参阅:Observer pattern。

以上是关于Android 从 Service 到 Client 的通信的主要内容,如果未能解决你的问题,请参考以下文章

Android 从 Service 到 Client 的通信

Android:将参数从Activity传递给Service

Android Service调用流程解析

如何从后台service传递数据到前台正在运行的activity

Android:需要一个使用的想法:Service、Thread、AsyncTask 或其他东西

Android 中的 Service 全面总结详解下