Я создал службу переднего плана, которая работает с работающим объектом, который запланирован через некоторое время. Работает долго. Сначала у меня был этот код в сервис:
private final Handler handler = new Handler();
...
...
public int onStartCommand(...
handler.postDelayed(sendUpdatesToUI, 50);
...
private Runnable sendUpdatesToUI = new Runnable() {
public void run() {
try {
DBAdapter DB = new DBAdapter(MyService.this);
DB.open();
DB.insertData(System.currentTimeMillis(), "",
cronometro.tiempo_original, 0) ;
DB.close();
} catch (Exception e) {
Toast.makeText(MyService.this, e.toString(),Toast.LENGTH_LONG).show();
}
SendInfo();
handler.postDelayed(this, 300000);
}
};
Но в приведенном выше коде есть проблема: обработчик запускается в потоке пользовательского интерфейса, поэтому, если действия пользовательского интерфейса не находятся в памяти, функция с задержкой не работает, так как рабочий поток больше не активен. Поэтому я изменил код, чтобы использовать системный планировщик между планировщиком (обработчиком) конкретной активности. Теперь код выглядит так:
private final ScheduledExecutorService schedulerService = Executors.newScheduledThreadPool(1);
private ScheduledFuture scheduleFuture;
...
...
public int onStartCommand(...
scheduleFuture = schedulerService.schedule(sendUpdatesToUI,50, TimeUnit.MILLISECONDS);
...
private Runnable sendUpdatesToUI = new Runnable() {
public void run() {
try {
DBAdapter DB = new DBAdapter(MyService.this);
DB.open();
DB.insertData(System.currentTimeMillis(), "",
cronometro.tiempo_original, 0) ;
DB.close();
} catch (Exception e) {
Toast.makeText(MyService.this, e.toString(),Toast.LENGTH_LONG).show();
}
SendInfo();
scheduleFuture = schedulerService.schedule(sendUpdatesToUI,300000,TimeUnit.MILLISECONDS);
}
};
Этот второй код является правильным способом сделать это для долгой службы, деятельность которой не будет впереди.
Как видите, код делает то же самое, но он позволяет избежать проблемы использования обработчика, который зависит от основного потока пользовательского интерфейса.
Если я прокомментирую код SQL для обоих, они отлично работают, пока основное действие находится на вершине. Но если я не комментирую SQL-код, второй пример зависает и не запускается. Он останавливается на sqlcode, потому что DatabaseHelper нужен действительный контекст, а поскольку executors является системным контекстом, он не работает. Любой контекст, который я помещаю в DBAdapter (context) (например, getApplicationContext (), getBaseContext () или MyService.this), не работает.
Кто-нибудь знает, как я могу предоставить действительный контекст для второго примера?