2016-08-12 62 views
3

我有一个名为MainActivity的Activity启动一个名为MainService的服务。它也绑定了服务,所以MainActivity可以访问MainService中的方法和公共变量。是否有可能以相反的方式做到这一点,即服务能够访问活动的方法?服务可以访问活动中的变量吗?

我希望以这种方式实现它,因为我在onResume()中设置了MainActivity中的一个变量,并且在第一次启动时服务在onResume()运行时尚未启动,因此在那个时间点该服务仍然为空。

+0

我从意向服务中的应用程序类访问变量。不确定活动。 –

+0

为什么不使用共享属性呢? –

+1

我不认为它可以。我也叫这个糟糕的设计。服务应该独立于UI的东西。如果服务需要来自UI的值,请设计UI以在服务中设置值。 –

回答

1

这个回答假设问题的服务在不同的进程中运行:

是的,这是可能的。总体思路是,不仅您的Activity通过某个AIDL定义的接口绑定远程Service,而且它还实现了Service所知的其他AIDL接口,并将其自身设置为远程Service的回调目标。

您必须有2个AIDL文件:第一个描述Service的接口,第二个描述Activity的接口。

这种方案的实施是非常相似的“远程服务回调”,在this answer来形容,虽然“回调”的方法将不再是void,但回报你感兴趣的值。

设计注意事项:

上述方案将允许您从Activity获得值,但我认为您不应该采取这种方式。从你的用例的描述看来,当Activity恢复时,你只想将某个值传递给Service。由于您的Service已被绑定,您可以简单地将方法setSomeValue(int value)添加到其AIDL定义中,并从onServiceConnected()回调中调用此方法。

+1

仅当您想在不同应用程序之间共享服务时,才需要AIDL文件。 – piotrpo

+0

@piotrpo,好点!我只是假定涉及IPC,但现在我发现在服务所处的过程中没有提到它。 – Vasiliy

0

是的,这是可能的。 你必须在你的服务做准备的方法即可返回您的活动服务绑定刚过:

public void bindActivity(MyActivity activity){...} 

然后服务绑定到活动后,只需要调用此方法MyActivity.this作为参数。

但是...

你可能不应该这样做。更为明确的解决方案是使用LocalBroadcastManager传递事件和数据,或者使用一些更有效的解决方案(如Otto)来做同样的事情,但仍然是 - 无需从另一个组件的字段/方法直接访问。

+0

“服务”依赖于“活动”并不是一个好主意。如果这个方法的参数是某个接口,并且'MainActivity'只是简单地实现它,那将会更加干净。 – Vasiliy

+0

在我看来,唯一真正“干净”的解决方案就是一些基于消息的解决方案。当然,根据OOD规则引入一些接口是个好主意,但仍然是 - 这个问题不是关于设计,而是实现。 – piotrpo

+0

不需要消息传递 - “服务”被绑定,因此只需一个简单的函数调用即可。接口是实现的一部分,否则实现不干净;) – Vasiliy

相关问题