Android 安卓系统返回一个";“生活”;对象,该对象来自绑定到AIDL的服务

Android 安卓系统返回一个";“生活”;对象,该对象来自绑定到AIDL的服务,android,android-service,ipc,aidl,Android,Android Service,Ipc,Aidl,我想创建一个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.setEna

我想创建一个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);
前者是一种更加面向对象的方法,而后者则更具功能性


谢谢。

只要
IFoo
IBar
IBaz
都是通过AIDL定义的,就可以了。

只要
IFoo
IBar
IBaz
都是通过AIDL定义的,这应该很好。

在Commonware的评论2中提供了一个明确的建议示例

首先,定义要从主AIDL接口返回的子AIDL接口

interface IMyService {
  IFoo getFoo();
}
interface 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();
  }
}
IFoo
本身应该是一个AIDL接口

interface IMyService {
  IFoo getFoo();
}
interface 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();
  }
}
在实现
IMyService.getFoo()
时,构造一个新的绑定器,并将其作为
IFoo
接口返回

interface IMyService {
  IFoo getFoo();
}
interface 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();
  }
}

在Commonware的评论#2中提供了一个清晰的建议示例

首先,定义要从主AIDL接口返回的子AIDL接口

interface IMyService {
  IFoo getFoo();
}
interface 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();
  }
}
IFoo
本身应该是一个AIDL接口

interface IMyService {
  IFoo getFoo();
}
interface 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();
  }
}
在实现
IMyService.getFoo()
时,构造一个新的绑定器,并将其作为
IFoo
接口返回

interface IMyService {
  IFoo getFoo();
}
interface 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();
  }
}

“通过AIDL定义”,你的意思是我为他们提供了一个.AIDL接口。。。然后我只返回一个实现该接口的对象?该对象是否需要是可包裹的?只有当它包含方法之外的数据时?@JeffreyBlattman:“你的意思是我为它们提供了一个.aidl接口”——是的。“那么我只返回一个实现该接口的对象?”--不,您可以像处理活页夹一样,对
.Stub
进行子类化。“这个东西需要用包裹吗?”——不,事实上,我怀疑这是否行得通。“仅当它包含方法之外的数据时?”--数据没有移动。AIDL公开方法。基本上,这是通过网络发送纯数据(例如REST Web服务)和通过网络发送纯行为(例如SOAP Web服务)之间的区别。@JeffreyBlattman:我没有您的场景示例,但我有一个相关的示例:回调。为了让客户端向服务提供回调对象,需要定义回调AIDL,让客户端实现
.Stub
,并将该
.Stub
的实例传递给绑定器上接受回调实例的某个方法。该服务获取AIDL定义接口的实例,并可以对其调用方法。确实,你在第二条评论中的建议是有效的。我将编辑您的答案,以提供一个明确的例子。“数据没有移动。AIDL公开方法。”-这是一个关键点。您可以返回操作或数据,但不能同时返回操作或数据。呃,发布了一个新答案,以避免损坏您的帖子。通过“通过AIDL定义”,您的意思是我为它们提供了一个.AIDL接口。。。然后我只返回一个实现该接口的对象?该对象是否需要是可包裹的?只有当它包含方法之外的数据时?@JeffreyBlattman:“你的意思是我为它们提供了一个.aidl接口”——是的。“那么我只返回一个实现该接口的对象?”--不,您可以像处理活页夹一样,对
.Stub
进行子类化。“这个东西需要用包裹吗?”——不,事实上,我怀疑这是否行得通。“仅当它包含方法之外的数据时?”--数据没有移动。AIDL公开方法。基本上,这是通过网络发送纯数据(例如REST Web服务)和通过网络发送纯行为(例如SOAP Web服务)之间的区别。@JeffreyBlattman:我没有您的场景示例,但我有一个相关的示例:回调。为了让客户端向服务提供回调对象,需要定义回调AIDL,让客户端实现
.Stub
,并将该
.Stub
的实例传递给绑定器上接受回调实例的某个方法。该服务获取AIDL定义接口的实例,并可以对其调用方法。确实,你在第二条评论中的建议是有效的。我将编辑您的答案,以提供一个明确的例子。“数据没有移动。AIDL公开方法。”-这是一个关键点。您可以返回操作或数据,但不能同时返回两者。错误,发布了一个新答案,以避免损坏您的帖子。您应该能够返回
new FooBinder()
,而无需使用
IFoo.Stub.asiinterface()
。事实上,我希望
IFoo.Stub.asInterface()
会引起问题
新FooBinder()
工作正常。在
IFoo
中调用该方法时,将从android.os.Parcel.readException(Parcel.java:1624)的
中得到
java.lang.IllegalArgumentException:Format specifier:s
错误,而不需要
IFoo.Stub.asInterface()
。事实上,我希望
IFoo.Stub.asInterface()
会引起问题
新FooBinder()
工作正常。在
IFoo
中调用该方法时,将从android.os.Parcel.readException(Parcel.java:1624)的
中得到
java.lang.IllegalArgumentException:Format specifier:s
错误