为什么在某些诺基亚手机上,在Java中调用cancelQuery来取消时代码会挂起,蓝牙查询



我在装有 S40 的诺基亚设备上遇到问题(但在 S60 上没有)。问题是这样的:当您从同步块中调用发现代理的cancelQuery方法时,它挂了。它实际上应该回调查询已完成。代码只是冻结 - 永远不会进入查询已完成方法。如果完成了同样的事情,但不是从同步块中完成的 - 一切正常。问题是我需要同步块,以便其中的所有内容都在多线程应用程序中原子地执行。

这是我的发现侦听器的样子:

public class DeviceDiscoverer implements DiscoveryListener {
   private Object thisCannotBeInterruptedByOtherBlocksLikeIt=new Object();
   private boolean stiiInCycle;
   private DiscoveryAgent discoveryAgent;
   public boolean cancel() { //called from some controller in mid discovery
      //synchronized(thisCannotBeInterruptedByOtherBlocksLikeIt) //problem when this is uncommented
      {
         if (stillInCycle) {
             //<some logic>
             discoveryAgent.cancelInquiry(this);
             //<more logic>
         }
      }
   }
   public void inquiryCompleted(int inquiryStatus) { //this is a callback in response to cancel or normal ending
      Beeper.beep(); //this makes the phone make a sound
   }
   // <some irrelevant methods here. some have synchronized blocks like the one above>
}

当您在 S40 和 S60 上运行上述代码时,同步语句被注释掉,并调用 cancel() 方法,立即调用 inquiryCompleted 方法,您会听到哔哔声。但是,如果您取消注释同步语句,您会在 S60 上听到哔哔声,但在 S40(至少在第 5 版 fp1 上),永远不会调用查询已完成!(当我在调用发现代理的取消查询之前发出哔哔声stmt时,它发出了哔哔声。 当我在那个电话之后放置它时,它没有到达那里。 那是因为呼叫没有返回,直到它调用查询已完成并且该调用没有发生)

问题出在哪里? 如果这是 S40 的取消查询的 IMPL'n 中的错误,我该如何解决它?我必须同步,因为事情是并行完成的(例如,我的代码可能会启动查询然后,可以取消它。在取消时,startInquiry 可能正在运行,设备发现可能正在运行,查询已完成可能正在运行,当然与其中任何一个并行,传入的 cancelInquiry可能正在运行。

换句话说,我试图将查询完成到另一个侦听器实例中,而不是调用discoveryAgent.cancelInquiry(this)我称之为discoveryAgent.cancelInquiry(otherInstance),希望查询在"另一个实例"中完成将被调用,但不,它也以这种方式挂起。

有什么建议吗?提前致谢

我不喜欢这种方法,但是,由于您不能使用同步...繁忙的等待循环怎么办?http://en.wikipedia.org/wiki/Busy_wait

您可以尝试以下代码:

   私有线程取消线程;    公共布尔值取消() {        同步(这) {            而 (取消线程 != 空) {                try { Thread.sleep(100); } catch(Exception e) {}            }            cancelThread = Thread.currentThread();        }        做你的事情        取消线程 = 空;返回前    }

最新更新