AltBeacon: сообщение задержано в didEnterRegion/didExitRegion

DidEnterRegion и didExitRegion вызываются из BeaconIntentProcessor onHandleIntent. Учитывая природу onHandleIntent и тот факт, что он завершается в конце всего метода, он не может выполнять вызовы postDelayed внутри него.

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

Каковы общие рекомендации, если мне нужно выполнить отложенный вызов метода либо в didEnterRegion, либо в didExitRegion? Использую ли я для этого менеджер сигналов тревоги? Я не хочу, так как это кажется немного тяжелым, просто чтобы иметь возможность выполнить отложенное действие.


person Qin Zhengquan    schedule 24.12.2015    source источник
comment
Вы уверены, что проблема не в том, что обработчик собирает мусор? Что, если вы измените область действия объекта Handler, чтобы он стал членом родительского объекта?   -  person davidgyoung    schedule 25.12.2015
comment
Привет, Дэвид, как указано в моем ответе ниже, обработчик собирает мусор, когда onHandleIntent завершается, если обработчик был создан в методе. Следовательно, ваш подход также будет работать, и я проверил его, если обработчик был создан в отдельном потоке (например, вызов одноэлементного класса и инициализация переменной класса обработчика) в отдельной службе перед вызовом одноэлементных методов в событии onEnterRegion.   -  person Qin Zhengquan    schedule 25.12.2015


Ответы (1)


Обновление: я заменил нативную задачу таймера/таймера Java или ScheduledExecutorService, и она работает хорошо. Оба они создают новый поток, который выживает после завершения onHandleIntent, в отличие от обработчиков, которые присоединены к создавшему его потоку. Поэтому, если вы создаете новый обработчик в службе намерений onHandleIntent, обработчик умирает, когда onHandleIntent завершает выполнение.

Обновление: в качестве альтернативы, как предложил Дэвид Янг, создайте обработчик в отдельном потоке (например: создание экземпляра обработчика как переменной класса в одноэлементном классе, работающем в основном потоке или отдельной службе), прежде чем вызывать его методы, когда AltBeacon didEnterRegion/didExitRegion называется. Что бы вы ни делали, не создавайте новый объект обработчика с отложенной публикацией в onHandleIntent, поскольку обработчик будет присоединен к потоку службы намерений и умрет вместе с ним, когда завершит выполнение, тем самым не выполняя исполняемый объект с отложенной публикацией.

ScheduledExecutorService рекомендуется в отличие от собственной задачи таймера/таймера по причинам, указанным в 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); 
}
person Qin Zhengquan    schedule 24.12.2015