0

The didEnterRegion and didExitRegion are called from BeaconIntentProcessor onHandleIntent. Given the nature of onHandleIntent and the fact that it terminates at the end of the method all, its not able to run postDelayed calls within it.

.....
@Override
public void didEnterRegion(Region region){
  Handler handler = new Handler();
  handler.postDelayed(new Runnable(){
     @Override
     public void run(){
        // not run after 60 seconds 
     }
  }, 60000);
}
...

What are the general best practices if I need to execute a delayed method call within either didEnterRegion or didExitRegion? Do I use an alarm manager for this? I'm reluctant to as it seems a little heavy weight just to be able to execute a delayed action.

Qin Zhengquan
  • 467
  • 1
  • 8
  • 20
  • 1
    Are you sure the issue is not that the Handler is getting garbage collected? What if you change the scope of the Handler object to be a member of the parent object? – davidgyoung Dec 25 '15 at 00:01
  • Hi David, as provided in my answer below, the handler is garbage collected when the onHandleIntent finishes if the handler was created within the method. Hence your approach will work as well and I've tested it, if the handler was created on a separate thread, (eg calling the singleton class and initialising handler class variable) on a separate service before invoking the singleton methods in the onEnterRegion event. – Qin Zhengquan Dec 25 '15 at 00:31

1 Answers1

0

Update: I've replaced with the native Java timer/timer task or ScheduledExecutorService and it works well. Both of them spins off a new thread which survives onHandleIntent termination unlike handlers which is attached to the thread that created it. So if you create a new handler in the intent service onHandleIntent, the handler dies when onHandleIntent finishes executing.

Update: Alternatively, as suggested by David Young, create the handler on a separate thread (eg: instantiating the handler as a class variable in a singleton class running on a main thread or separate service) before invoking its methods when AltBeacon didEnterRegion/didExitRegion is called. Whatever you do, do not create a new handler object with post delayed within onHandleIntent as the handler will be attached to the intent service thread and die with it when it finishes executing, thereby not executing the runnable in post delayed.

ScheduledExecutorService is advocated as opposed to the native timer/timer task for reasons stated in Java Timer vs ExecutorService?.

private static final ScheduledExecutorService mWorker = Executors.newSingleThreadScheduledExecutor();

@Override
public void didEnterRegion(Region region){
  new Timer().schedule(new TimerTask(){
     @Override
     public void run (){
        // remember to free timer after using it
        // it runs after didEnterRegion finishes execution, and after 60 seconds
     }
  }, 60000); 
}

@Override
public void didEnterRegion(Region region){
  mWorker.schedule(new Runnable(){
     @Override
     public void run (){
        // it runs after didEnterRegion finishes execution, and after 60 seconds
     }
  }, 60000); 
}
Community
  • 1
  • 1
Qin Zhengquan
  • 467
  • 1
  • 8
  • 20