。それは長い間実行されます。最初は私がサービスにこのコードを持っていた:サービスschedulefutureやデータベースの競合
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);
}
};
をしかし、上記のコードは、問題があります。ハンドラは、UIスレッドで実行されるので、UIの活動がメモリにない場合postdelayed機能は、作業としては動作しません。スレッドはもはやアクティブではありません。そこで、アクティビティ固有のスケジューラ(ハンドラ)の間でシステムスケジューラを使用するようにコードを変更しました。今のコードは次のようになります。
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);
}
};
この第二のコードは、活動が前であることを行っていない長いサービスのためにそれを行うための正しい方法です。 あなたがコードを見ることができるように同じことを行うが、それは、メインUIスレッドでdepentハンドラを使用しての問題を回避します。
私は両方のためのSQLコードをコメントしている場合、彼らは限り主な活動は、一番上にあると完璧に実行。しかし、私はコメントSQLコードをしない場合、2番目のサンプルがハングし、実行されません。 DatabaseHelperは有効なコンテキストを必要とし、executorはシステム・コンテキストなので実行されないため、sqlcodeで停止します。 getApplicationContext()、getBaseContext()、またはMyService.thisのようなDBAdapter(コンテキスト)に入れたコンテキストは機能しません。
誰もが2番目の例に有効なコンテキストを提供する方法を知っていますか?
私はこの問題に完全に見当たらず、AlarManagerを使用するのは控えめでしたが、今は私がそれを行う方法であると分かっていて、予想以上に簡単です。また、サービスクラスをintentserviceにアップグレードしても、完璧に機能し、バッテリーの消費を抑えることができます。ありがとう。 – Tibor