我的应用中有一个设置为运行AsyncTask的Firebase 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 的片段的"Stop"事件被调用时,它会取消 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"事件中被杀死。仅当应用在前台运行时,才需要该服务。
添加蛋监控器服务代码
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) ;
}
}
}
谢谢。 席德
如果取消AsyncTask
,则调用onCancelled()
而不是onPostExecute()
。从那里拨打jobFinished()
:
@Override
protected void onCancelled(Void aVoid){
Log.d(TAG, "Cancelling ... ");
jobFinished(jobParameters, false) ;
}
另外,处理ValueEventListener
中的错误:
@Override
public void onCancelled(@NonNull DatabaseError databaseError) {
Log.w(TAG, "Error: " + databaseError.toString());
keepGoing = false;
}