我尝试使用TimerTask从服务器api下载数据,任务循环在后台app。
我有一个服务类:
public class RequestNewInvoice extends Service {
private Timer timer;
private CheckTask checkTask;
private Handler handler;
private JSONParser jsonParser;
private JSONObject jsonObject;
private boolean startService = true;
private void init(){
this.handler = new Handler(new Handler.Callback() {
@Override
public boolean handleMessage(Message msg) {
Log.e("Message: ",msg.obj+"");
return false;
}
});
this.timer = new Timer();
this.checkTask = new CheckTask();
this.startService = true;
timer.scheduleAtFixedRate(checkTask, 5000, 20 * 1000);
}
@Override
public IBinder onBind(Intent intent) {
return null;
}
@Override
public int onStartCommand(final Intent intent, int flags, final int startId) {
init();
return START_STICKY;
}
@Override
public void onDestroy() {
super.onDestroy();
Log.e("SERVICE STOP", "true");
startService = false;
checkTask.cancel();
timer.cancel();
timer.purge();
}
private class CheckTask extends TimerTask{
@Override
public void run() {
funcCheckInvoice();
}
}
public void funcCheckInvoice(){
try{
if(startService){
Log.e("SERVICE START", "true");
HttpParams httpParameters = new BasicHttpParams();
HttpConnectionParams.setConnectionTimeout(httpParameters, SuperVAR.GET_CURRENT_SHIPMENT_TIMEOUT);
HttpConnectionParams.setSoTimeout(httpParameters, SuperVAR.GET_CURRENT_SHIPMENT_TIMEOUT);
httpClient = new DefaultHttpClient(httpParameters);
HttpGet httpGet = new HttpGet(SuperVAR.URL_GET_LIST_INVOICE_IN_CURRENT_SHIPMENT+"?"+ URLEncodedUtils.format(_REQUEST, "utf-8")+"unused="+System.currentTimeMillis()/1000);
httpGet.setHeader("token",token);
httpGet.setHeader("Cache-Control","no-cache");
httpGet.setHeader("Cache-Control","no-store");
HttpResponse httpResponse = httpClient.execute(httpGet);
HttpEntity httpEntity = httpResponse.getEntity();
jsonObject = jsonParser.getJSONFromRESPONSE(httpEntity);
if(jsonObject == null){
Message message = Message.obtain();
message.obj = "get null.... internet like shit T_T";
handler.sendMessage(message);
}else {
Message message = Message.obtain();
message.obj = "download ok";
handler.sendMessage(message);
}
}else {
Log.e("SERVICE START", "false");
return;
}
}catch (Exception e){
e.printStackTrace();
}
}
}
当我在Activity Class中运行stopService时,服务调用onDestroy函数,但Timer仍然存在。
如何销毁计时器任务?
答案 0 :(得分:1)
使用Handler并在destroy上删除回调任务
TimerTask scanTask;
final Handler handler = new Handler();
Timer t = new Timer();
scanTask = new TimerTask() {
public void run() {
handler.post(task);
}};
t.schedule(scanTask, 5000, 20 * 1000);
Runnable task = new Runnable() {
@Override
public void run() {
//START YOUR JOB
(new FetchData()).execute();
}
};
@Override
public void onDestroy() {
super.onDestroy();
Log.e("SERVICE STOP", "true");
startService = false;
checkTask.cancel();
timer.cancel();
timer.purge();
handler.removeCallbacks(task);
}
public class FetchData extends AsyncTask<Void, Void, Void>
{
@Override
protected Void doInBackground(Void... params)
{
funcCheckInvoice();
}
}
答案 1 :(得分:0)
您已将服务作为START_STICKY启动,这可能就是原因所在 你不能停止服务。
以下是START_STICKY的definition。
从onStartCommand(Intent,int,int)返回的常量:如果是这样 服务的进程在启动时被终止(在返回之后) onStartCommand(Intent,int,int)),然后将其保持在启动状态 但不要保留这个意图。稍后系统会尝试 重新创建服务。因为它处于启动状态,它会 保证在创建后调用onStartCommand(Intent,int,int) 新服务实例;如果没有任何挂起的启动命令 如果被传递给服务,它将被调用null意图 对象,所以你必须注意检查这个。
此模式适用于将明确启动的内容 停止运行任意时间段,例如服务 表演背景音乐播放。
尝试使用START_NOT_STICKY
您还需要在呼叫时更改呼叫取消的方式 scheduleAtFixedRate。
private ScheduledThreadPoolExecutor scheduleTaskExecutor;
private ScheduledFuture schedule;
...
scheduleTaskExecutor = (ScheduledThreadPoolExecutor) Executors.newScheduledThreadPool(5);
schedule = scheduleTaskExecutor.scheduleAtFixedRate(checkTask, 5000, 20 * 1000);
@Override
public void onDestroy()
{
super.onDestroy();
startService = false;
checkTask.cancel();
schedule.cancel(true);
}