12

(我有一个带有 AIDL 接口的远程服务,该接口被多个客户端应用程序使用。我想为需要一些时间的调用向接口添加一个异步方法,但我需要安全的解决方案,这意味着只有我的应用程序可以与服务通信,客户端应用与服务应用签名相同,目前应用只是绑定服务,调用单一接口方法进行各种操作。

一种选择是在操作完成时从服务中广播 Intent 并在客户端应用程序中使用 BroadcastReceiver,但是(问题 #1)可以通过确保只有我的应用程序可以接收 Intent 的方式来完成吗?setPackage() 似乎可以做到这一点,但我需要支持 Gingerbread 设备,这似乎根据这里的答案排除了这种方法:setPackage for intent ingingerbread

所以看来我需要添加第二个 .aidl 接口和回调接口供服务使用,由客户端实现。我在这里看到了使用侦听器的示例,但我不确定与仅将第二个接口对象作为参数传递的客户端有什么区别(如该答案的 IScript / IScriptResult 示例中使用的那样:Service call backs to activity in安卓

问题 #2,在这里使用监听器与回调方法有什么好处?

4

1 回答 1

26

回调方法/侦听器是正确的做法。(正如 CommonsWare 所说,这几乎是一回事)。我想说这比摆弄广播接收器要简单得多,因为您已经在使用aidl。

像这样的东西:

IAsyncThing.aidl:

package com.my.thingy;

import com.my.thingy.IAsyncThingListener;

interface IAsyncThing {
  void doSomething(IAsyncThingListener listener);
}

IAsyncThingListener.aidl:

package com.my.thingy;

import com.my.thingy.IAsyncThingListener;

interface IAsyncThingListener {
  void onAsyncThingDone(int resultCodeIfYouLike);
}

您可以通过对服务使用签名级权限来强制只有您的应用可以绑定到服务(请参阅此处的“服务权限”说明:http: //developer.android.com/guide/topics/security/permissions .html)。具体来说:

  • 在您的服务的AndroidManifest.xml. 确保它是signature水平的。
  • service在您的标签中添加该权限
  • 在所有其他应用程序中,uses-permission使用它。

其他几件事要记住:

  • 在调用者中,您需要子类化IAsyncThingListener.Stub. 您的调用应用程序代码可能已经继承了其他东西,这意味着您必须使用额外的(可能是内部的)类来接收完成通知。我提到这一点只是因为这可能是问题 #2 的答案——我并不完全理解。
  • 如果服务可能与调用者处于不同的进程中,则每个进程都应使用IBinder.linkToDeath.
于 2013-01-30T09:37:37.047 回答