В моем приложении есть Firebase JobDispatcher, настроенный для запуска AsyncTask.JobDispatcher создается:
dispatcher = new FirebaseJobDispatcher(new GooglePlayDriver(getContext())) ;
monitorEggJob = dispatcher.newJobBuilder()
.setService(EggMonitorJobService.class)
.setTag(JOB_TAG)
.setLifetime(Lifetime.UNTIL_NEXT_BOOT)
.setRecurring(false)
.setReplaceCurrent(true)
.setConstraints(Constraint.ON_ANY_NETWORK)
.build() ;
dispatcher.mustSchedule(monitorEggJob);
Когда вызывается событие «Стоп» фрагмента, запустившего этот JobDispatcher, он отменяет JobService:
int result ;
if ( dispatcher != null )
{
result = dispatcher.cancel(JOB_TAG) ;
Log.d(TAG, "Dispatcher cancelled Egg Monitor Task (Result = " + result + "(");
}
Результат - «0»,означает успех.
Однако, когда приложение было закрыто, через некоторое время JobService снова запускает AsyncTask, и возникает исключение:
Caused by: java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare()
Кроме того, если я посмотрю на "«Информация о приложении» после того, как приложение было полностью закрыто, а не только в заднем стеке, доступна опция «принудительная остановка», указывающая, что Диспетчер все еще работает, я думаю.
Мой вопрос заключается в том, как я могу обеспечитьдиспетчер убит в событии "onStop".Служба требуется только во время работы приложения на переднем плане.
*********** Добавить код EggMonitorService ************
public class EggMonitorJobService extends JobService {
private EggMonitorTask eggMonitorTask ;
private boolean keepGoing ;
private JobParameters jobParameters ;
@Override
public boolean onStartJob(JobParameters job) {
jobParameters = job ;
keepGoing = true ;
eggMonitorTask = new EggMonitorTask();
eggMonitorTask.execute() ;
return true;
}
@Override
public boolean onStopJob(JobParameters job) {
//keepGoing = false ;
if ( eggMonitorTask != null ) {
eggMonitorTask.cancel(true) ;
}
return false;
}
private class EggMonitorTask extends AsyncTask<Void, Void, Void> {
public static final String TAG = "EggMonitorTask" ;
@Override
protected void onPreExecute() {
Log.d(TAG, "Starting ...");
super.onPreExecute();
}
@Override
protected Void doInBackground(Void... voids) {
final DatabaseReference eggsReference = FirebaseDatabase.getInstance().getReference().child("eggs") ;
Query query = eggsReference.orderByChild("userKey") ;
final ValueEventListener listener = new ValueEventListener() {
@Override
public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
//
List<EggModel> eggs = new ArrayList<>() ;
for ( DataSnapshot snapshot : dataSnapshot.getChildren() ) {
EggModel egg = snapshot.getValue(EggModel.class) ;
eggs.add(egg) ;
}
if ( eggs.size() > 0 ) {
for ( EggModel item : eggs ) {
//
// Run the hatch date and write
// any updated data to database
//
if ( item.updateHatchSoon() ) {
//
// Update database
//
eggsReference.child(item.getDbKey()).setValue(item) ;
}
}
}
//
// All done
//
keepGoing = false ;
}
@Override
public void onCancelled(@NonNull DatabaseError databaseError) {
}
} ;
query.addValueEventListener(listener) ;
//
// Sleep until all the work has been completed,
// check for completion periodically.
//
while(keepGoing) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
query.removeEventListener(listener);
return null;
}
//
// There is no return data, this is here for
// debug only
//
@Override
protected void onPostExecute(Void aVoid) {
Log.d(TAG, "Ending ...");
jobFinished(jobParameters, keepGoing) ;
}
}
}
Спасибо.Sid