【问题标题】:Design Pattern in Bound Service?绑定服务中的设计模式?
【发布时间】:2015-12-24 16:39:13
【问题描述】:

我正在探索 Android 中的绑定服务。我在 Android 开发人员文档中遇到了关于 Bound service 的以下行。

多个客户端可以同时连接到服务。然而 系统调用您的服务的 onBind() 方法来检索 IBinder 仅当第一个客户端绑定时。然后系统提供相同的 IBinder 绑定到任何其他绑定的客户端,而不调用 onBind() 再次。

正如这里提到的,Android 系统似乎正在使用已经存在的IBinder 来返回其他客户端。

这个实现是否松散地基于享元设计模式的概念?众所周知,享元模式主要用于减少创建的对象数量,减少内存占用并提高性能。

更新:

我检查了处理此代码的 Android 源代码。 如下:

if (!data.rebind) {
                        IBinder binder = s.onBind(data.intent);
                        ActivityManagerNative.getDefault().publishService(
                                data.token, data.intent, binder);
                    } else {
                        s.onRebind(data.intent);
                        ActivityManagerNative.getDefault().serviceDoneExecuting(
                                data.token, SERVICE_DONE_EXECUTING_ANON, 0, 0);
                    }

data.rebind 只是一个布尔值,在静态类中声明如下,data 是这个BindServiceData 类的对象。

static final class BindServiceData {
        IBinder token;
        Intent intent;
        boolean rebind;
        public String toString() {
            return "BindServiceData{token=" + token + " intent=" + intent + "}";
        }
    }

因此,也许它与享元模式没有直接关系。

【问题讨论】:

  • android/app/ActivityThread.java

标签: android design-patterns service


【解决方案1】:

我不认为这在技术上是对享元模式的使用。有一些相似之处,但两者之间存在一些细微差别。

来自WIKI page

享元是一个通过共享尽可能多的内存来最小化内存使用的对象 尽可能与其他类似对象的数据;这是一种使用方式 当一个简单的重复表示会出现大量对象时 使用不可接受的内存量。

然后

享元模式的一个典型用法是数据结构 文字处理器中字符的图形表示。对于文档中的每个字符,可能需要一个包含其字体轮廓、字体度量和其他格式数据的字形对象,但这对于每个字符来说将达到数百或数千字节。相反,对于每个字符,都可能引用文档中同一字符的每个实例共享的享元字形对象;只有每个字符的位置(在文档和/或页面中)需要在内部存储。

这描述了一个场景,其中您有大量对象,如果每个对象都将其“完整数据”存储在每个对象中,则需要大量内存。 Flyweight 模式用于在大量对象(例如文本编辑器中的字符)通常具有相同的值集(例如字体大小、字体类型、颜色、背景颜色等)时对内存使用进行重复数据删除。他们只是在它们之间共享一个“flyweight”对象来存储该数据。 (将每个对象的多个变量对内存的影响减少到只是一个指针)

Android 绑定服务会在服务启动时创建一个新的 ibinder,如果新客户端“也碰巧”在服务启动时绑定到该服务,则将相同的 ibinder 实例返回给新客户端。然而,与享元模式不同的是,在 Android 中完成的原因是因为只有 1 个绑定服务实例被启动。所以没有理由退回一个新的ibinder。 Android 服务没有内置任何并发安全性。因此,除非您从头开始设计服务以具有并发性并处理多个客户端,否则它们需要以无状态方式设计。这就是他们能够通过将并发问题放在开发人员而不是平台上来创建绑定服务的单个实例的方式。

仅将 ibinder 的单个实例分发给多个客户端并不能使其成为享元模式。如果有的话,我会认为它更接近单例模式。但这仍然是一个延伸,因为绑定服务的不同实例可以是不同的对象,这违反了单例模式。

【讨论】:

  • 你说的似乎很合适,我刚刚用来自 Android 的一些真实代码更新了我的问题,其中绑定的服务内容由 android 框架在内部处理。谢谢!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-11-26
  • 1970-01-01
  • 2012-08-21
  • 1970-01-01
  • 1970-01-01
  • 2015-09-19
  • 1970-01-01
相关资源
最近更新 更多