android 从 AIDL 绑定服务返回“活动”对象
Posted
技术标签:
【中文标题】android 从 AIDL 绑定服务返回“活动”对象【英文标题】:android returning a "live" object from an AIDL bound service 【发布时间】:2013-08-13 23:21:12 【问题描述】:我想创建一个 AIDL 服务,由于缺少正确的术语,该服务会返回“活动”对象。也就是说,我想要这样的工作,
IFoo foo = myService.getFoo(x); // calls to myService service to get an IFoo
IBar bar = foo.getBar(y); // IPC to IFoo to get an IBar
IBaz baz = bar.getBaz(z); // IPC to IBar to get an IBaz
baz.setEnabled(false); // IPC to IBaz to modify the service's copy of IBaz
我希望这是可能的,但我可以找到一个很好的例子。另一种方法是做类似的事情,
myService.setBazEnabled(x, y, z, false);
前者是一种更面向对象的方法,而后者更实用。
【问题讨论】:
【参考方案1】:只要 IFoo
、IBar
和 IBaz
都是通过 AIDL 定义的,就应该可以正常工作。
【讨论】:
通过“通过 AIDL 定义”,你的意思是我有一个 .aidl 接口给他们......然后我只返回一个实现该接口的对象?该对象是否需要为Parcelable
?仅当它包含除了方法之外的数据?
@JeffreyBlattman:“你的意思是我有一个 .aidl 接口给他们”——是的。 “那我只返回一个实现该接口的对象?” -- 不,你继承了.Stub
,就像你对你的活页夹所做的那样。 “对象需要是 Parcelable 吗?” - 不,事实上,我怀疑这是否有效。 “只有当它包含除了方法之外的数据?” - 数据没有移动。 AIDL 公开方法。基本上,这是通过网络发送纯数据(例如 REST Web 服务)和通过网络发送纯行为(例如 SOAP Web 服务)之间的区别。
@JeffreyBlattman:我没有你的场景的例子,但我有一个相关的例子:回调。为了让您的客户端向服务提供回调对象,您需要定义回调 AIDL,让客户端实现 .Stub
,并将该 .Stub
的实例传递给绑定器上接受回调实例的某个方法。该服务获取 AIDL 定义的接口的一个实例,并可以在其上调用方法。见github.com/commonsguy/cw-omnibus/tree/master/AdvServices/… 和github.com/commonsguy/cw-omnibus/tree/master/AdvServices/…
确实,您在第二条评论中的建议有效。我将编辑您的答案以提供一个明确的例子。 “数据没有移动。AIDL 暴露了方法。”——这是一个关键点。您要么返回操作,要么返回数据,但不能同时返回。
err,发布了一个新答案,以免破坏您的帖子。【参考方案2】:
在 CommonsWare 的评论 #2 中提供一个明确的建议示例 ...
首先,定义从主AIDL接口返回的子AIDL接口,
interface IMyService
IFoo getFoo();
IFoo
本身应该是一个AIDL接口,
interface IFoo
...
在IMyService.getFoo()
的实现中,构造一个新的绑定器,并将其作为IFoo
接口返回,
public class MyService implements Service
public class FooBinder extends IFoo.Stub
...
public class MyBinder extends IMyService.Stub
@Override
public IFoo getFoo()
return IFoo.Stub.asInterface(new FooBinder());
@Override
public IBinder onBind()
return new MyBinder();
【讨论】:
您应该能够返回new FooBinder()
,而无需IFoo.Stub.asInterface()
。事实上,我预计IFoo.Stub.asInterface()
会引起问题。
IFoo.Stub.asInterface(new FooBinder());
和 new FooBinder()
都不能正常工作。调用IFoo
中的方法时,会从at android.os.Parcel.readException(Parcel.java:1624)
得到java.lang.IllegalArgumentException: Format specifier: s
错误以上是关于android 从 AIDL 绑定服务返回“活动”对象的主要内容,如果未能解决你的问题,请参考以下文章