【问题标题】:Android: How to cancel/interrupt a synchronous Service call?Android:如何取消/中断同步服务调用?
【发布时间】:2013-02-12 15:14:03
【问题描述】:

对于应用程序对象,我调用bindService()onServiceConnected() 回调接收到 IBinder 对象,我将其交给 AsyncTask

在那里,我通过调用ServiceClass.Stub.asInterface(iBinderObject) 获取我的服务对象并使用此服务对象调用一些方法。

这是一个同步方法,我无法影响服务的超时设置(谁知道它的超时实现是否可靠)。所以,我事先在一个单独的线程上postDelayed()我自己的超时处理程序。

超时代码调用unbindService() 以解除应用程序与服务的绑定并产生超时结果。

如果超时先运行,我还没有找到中断服务调用的方法。 unbindService() 对此没有明显的影响。调用AsyncTask.cancel(true) 也没有任何改变。 IBinder 对象似乎没有提供任何可能有帮助的明显方法。

我观察到AsyncTask 一直在等待服务调用返回,这可能会显着延迟下一个AsyncTask 的启动与标准Executor

有什么经验吗?想法?

【问题讨论】:

  • 您的 AsyncTask 中是否有任何检查,以监视它是否使用 AsyncTask.isCancelled() 取消。如果你使用它,你可以简单地完成你的 AsyncTask,
  • @GauravArora 感谢您的评论。正如我所说,我想中断一个同步服务调用,我无法影响其代码。
  • 一般来说,同步呼叫是不能取消的。这就是为什么它们是同步的。但是您可以在超时处理程序启动后尝试停止服务。
  • @GauravArora 感谢您在超时处理程序中取消绑定后尝试停止服务的有希望的建议。它不会改变任何事情,大概是由于正在处理方法调用。当然,如果另一个应用程序绑定到该服务,它无论如何都不会工作。但它仍然很有价值。 -- 绑定一个服务,调用一个服务方法,涉及到binder线程和进程间通信,所以在我看来,中断调用是有一定概率的。尽管引用声称 DeadObjectException 是唯一抛出的异常。
  • ...所以,看看几个 API 参考,似乎唯一破坏性的 Android 方式来结束某事就是杀死一个进程。换句话说,避免由于服务无响应(如果应用程序要继续)而导致 AsyncTask 阻塞的唯一方法是为 AsyncTasks 使用 THREAD_POOL_EXECUTOR 或为服务调用创建最少的线程(引用尽可能少的资源) ,这样那些可以等待很长时间而不造成太大伤害的结果?

标签: android android-service request-cancelling


【解决方案1】:

正如其他人所指出的,同步调用不能被中断。

如果这是一个问题,并且您对服务 API 的设计有任何意见,您可以使用一对单向 AIDL 接口执行异步操作,如下所示:

package sample;
oneway interface IServer {
    void doWork(IClient cb);
}

package sample;
oneway interface IClient {
    void reportResult(String result);
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-12-03
    • 2012-06-17
    • 1970-01-01
    • 1970-01-01
    • 2010-09-22
    • 2010-10-31
    • 2023-04-03
    • 2018-07-20
    相关资源
    最近更新 更多