正在调用StopService onDestroy但服务未结束

时间:2015-05-13 03:43:10

标签: android service timer handler timertask

我尝试使用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仍然存在。

如何销毁计时器任务?

2 个答案:

答案 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);

}