我正在使用信标测距方法来发现和使用iBeacons。但是,在尝试迭代找到的所有信标时,我遇到了问题。
信标服务返回一个集合,我可以检查其大小,并看到有3个信标。然而,无论我尝试什么,我都可以可靠地遍历信标。我似乎每次都以不同的随机顺序进入信标,有些经常被跳过。
我尝试了while(iBeacons.iterator().hasNext())
,这只是冻结了我的应用。我已经尝试将我解析的lastBeacon与当前选择的信标进行比较并将其丢弃,但这并不能通过所有信标。
我认为,由于集合是异步更新的,并且我的解析所花费的时间远远超过在我有机会处理旧的信标之前添加的第二个新信标,而我似乎只是从集合中随机处理一个每一次。
每次如何获取和解析每个信标?
答案 0 :(得分:2)
代码很接近 - 它只需要在一个单独的行上构建Iterator
,如下所示:
Iterator<IBeacon> iterator = iBeacons.iterator();
while (iterator.hasNext())
冻结的原因与库的异步更新无关。 (传递给测距回调的iBeacons列表是在上一个扫描周期中看到的副本的副本,永远不会被更改。)问题与iterator()
方法在Java中的工作方式有关。
在上面的代码中,while(iBeacons.iterator().hasNext())
每次在循环内创建Iterator
的新副本,并且迭代器始终指向iBeacons集合中的第一个元素。因此,如果循环开始时该集合中至少有一个项目,它将永远不会完成,代码将冻结。
您可以使用以下示例演示此内容:
public class IteratorTest{
public static void main(String []args){
java.util.Collection iBeacons = java.util.Arrays.asList("1", "2", "3");
System.out.println("This loop will not freeze");
java.util.Iterator iterator = iBeacons.iterator();
while (iterator.hasNext()) {
System.out.println(iterator.next());
}
System.out.println("This loop will freeze");
while(iBeacons.iterator().hasNext()) {
System.out.println(iBeacons.iterator().next());
}
// We will never get to here
}
}
产生以下(永无止境)输出:
This loop will not freeze
1
2
3
This loop will freeze
1
1
1
1
1
1
1
1
1
1
1
1
1