我有一个应用程序使用该接口与Service
远程进程中的 a 进行通信。Messenger
以下是事物设置的基本架构:
- 应用程序生成几个需要访问服务的“操作”对象。
- 每个“操作”都包含一个
Handler
包裹在一个Messenger
用于接收从响应数据返回的Service
- 当操作执行时,它将其包装
Messenger
成一个Intent
并调用startService()
以将消息传递给远程服务 - 远程服务根据 的参数执行一些工作
Intent
,然后通过向该操作发送 aMessage
来返回响应Messenger
。
这是操作中存在的基本代码:
public class SessionOperation {
/* ... */
public void runOperation() {
Intent serviceIntent = new Intent(SERVICE_ACTION);
/* Add some other extras specific to each operation */
serviceIntent.putExtra(Intent.EXTRA_EMAIL, replyMessenger);
context.startService(serviceIntent);
}
private Handler mAckHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
//Process the service's response
}
};
protected Messenger replyMessenger = new Messenger(mAckHandler);
}
以及服务结构的片段(基本上是IntentService
在队列为空时不会关闭):
public class WorkService extends Service {
private ServiceHandler mServiceHandler;
private final class ServiceHandler extends Handler {
public ServiceHandler(Looper looper) {
super(looper);
}
@Override
public void handleMessage(Message msg) {
onHandleIntent((Intent)msg.obj);
}
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
//If intent has a message, queue it up
Message msg = mServiceHandler.obtainMessage();
msg.obj = intent;
mServiceHandler.sendMessage(msg);
return START_STICKY;
}
private void onHandleIntent(Intent intent) {
Messenger replyTarget = intent.getParcelableExtra(Intent.EXTRA_EMAIL);
/* Do some work */
Message delivery = Message.obtain(...);
replyTarget.send(delivery);
}
}
这一切都非常好。我可以将来自多个不同应用程序的大量操作发送到同一个服务,它们都会处理并将响应发送到正确的位置。然而...
我注意到,如果应用程序运行的时间足够长并且有足够的活动,它会以OutOfMemoryError
. 在查看 MAT 中的 HPROF 数据时,我注意到所有这些操作都保留在内存中,并且由于Messenger
. 显然,该Messenger
实例正在创建与 Binder 的长期本机连接,该连接算作 GC Root,它将每个“操作”对象无限期地保存在内存中。
有谁知道是否有办法Messenger
在“操作”结束时清除或禁用它,以免造成这种内存泄漏?是否有另一种方法可以以Service
相同的方式实现 IPC,以便多个不同的对象可以发出请求并异步获取结果?
提前致谢!