Android 远程服务回调
Posted
技术标签:
【中文标题】Android 远程服务回调【英文标题】:Android remote service callbacks 【发布时间】:2013-01-13 14:50:57 【问题描述】:(我有一个带有 AIDL 接口的 remote 服务,该接口被多个客户端应用程序使用。我想在接口中添加一个异步方法来处理需要一些时间的调用,但我需要解决方案是安全,这意味着只有我的应用程序可以与服务通信。客户端应用程序使用与服务应用程序相同的签名进行签名。目前应用程序只是绑定到服务并调用单个接口方法来执行各种操作。
一个选项是在操作完成时从服务中广播 Intent 并在客户端应用程序中使用 BroadcastReceiver,但是(问题 #1)可以通过确保只有我的应用程序可以接收 Intent 吗? setPackage() 似乎可以做到这一点,但我需要支持 Gingerbread 设备,根据这里的答案,这似乎排除了这种方法:setPackage for intent in gingerbread
所以看来我需要添加第二个 .aidl 接口和回调接口供服务使用,由客户端实现。我在这里看到了使用侦听器的示例,但我不确定与仅将第二个接口对象作为参数传递的客户端有什么区别(如该答案的 IScript / IScriptResult 示例中使用的那样:Service call backs to activity in android)
问题 #2,在这里使用监听器与回调方法相比有什么好处?
【问题讨论】:
监听器是回调方法。 【参考方案1】:回调方法/侦听器是正确的做法。 (正如 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
注册对方的死亡通知。
【讨论】:
如果我的服务调用回调并且绑定的应用程序不再处于活动状态/被移到后台,或者被系统杀死,会发生什么? 这就是IBinder.linkToDeath
位的用途。如果应用程序被终止,您会被告知。在所有其他情况下(例如它在后台),所有 IPC 通信应该仍然可以正常工作。
如果应用的activity绑定到我的服务并发出异步请求,但在调用回调时不再处于活动状态(不在屏幕上),是否仍会收到回调函数? Activity销毁时,私有回调stub对象不会被销毁吗?
您的活动通常不会因为不再出现在屏幕上而被销毁。只有在系统内存不足时,您的活动才会被销毁。
IAsyncThingListener.aidl
中的导入行有原因吗?以上是关于Android 远程服务回调的主要内容,如果未能解决你的问题,请参考以下文章