Question

I'm using the beacon ranging methods to discover and use iBeacons. However, I have run into problem while trying to iterate through all the beacons that were found.

The beacon service returns a collection, which I can check the size of and see there are 3 beacons. However, not matter what I try I can reliably iterate through the beacons. I seem to go in a different random order of beacons every time, and some are frequently skipped over.

I have tried while(iBeacons.iterator().hasNext()) and that just froze my app. I have tried comparing the lastBeacon which I parsed to the current beacon selected and throwing it out, but this didnt work to get through all beacons.

I think that since the collection is being update asynchronously and my parsing takes far longer than a second new beacons have been added before I ever get a chance to process the old ones, and I seems to just randomly process one from the collection each time.

How can I get and parse each beacon each time?

Was it helpful?

Solution

The code is close -- it simply needs to construct an Iterator on a separate line like this:

    Iterator<IBeacon> iterator = iBeacons.iterator();
    while (iterator.hasNext()) 

The reason your the freezes has nothing to do with asynchronous updates by the library. (The list of iBeacons passed to the ranging callback is a copy of those seen in the last scan cycle and never gets changed.) The problem has to do with the way the iterator() method works in Java.

In the code above, the while(iBeacons.iterator().hasNext()) creates a new copy of Iterator every time inside the loop, and that iterator is always pointing at the first element in the iBeacons collection. So if there is ever at least one item in that collection when the loop starts, it will never finish, and the code will freeze.

You can demonstrate this with the following example:

    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
         }

    }

Which produces the following (never ending) output:

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
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top